mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-19 00:04:52 -04:00
update MDAL 0.4.0
This commit is contained in:
parent
94fa3c44e0
commit
679e75e13c
13
external/mdal/api/mdal.h
vendored
13
external/mdal/api/mdal.h
vendored
@ -56,6 +56,7 @@ enum MDAL_Status
|
|||||||
Err_IncompatibleDatasetGroup,
|
Err_IncompatibleDatasetGroup,
|
||||||
Err_MissingDriver,
|
Err_MissingDriver,
|
||||||
Err_MissingDriverCapability,
|
Err_MissingDriverCapability,
|
||||||
|
Err_FailToWriteToDisk,
|
||||||
// Warnings
|
// Warnings
|
||||||
Warn_UnsupportedElement,
|
Warn_UnsupportedElement,
|
||||||
Warn_InvalidElements,
|
Warn_InvalidElements,
|
||||||
@ -105,6 +106,9 @@ MDAL_EXPORT bool MDAL_DR_meshLoadCapability( DriverH driver );
|
|||||||
//! Returns whether driver has capability to write/edit dataset (groups)
|
//! Returns whether driver has capability to write/edit dataset (groups)
|
||||||
MDAL_EXPORT bool MDAL_DR_writeDatasetsCapability( DriverH driver );
|
MDAL_EXPORT bool MDAL_DR_writeDatasetsCapability( DriverH driver );
|
||||||
|
|
||||||
|
//! Returns whether driver has capability to save mesh
|
||||||
|
MDAL_EXPORT bool MDAL_DR_SaveMeshCapability( DriverH driver );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns name of MDAL driver
|
* Returns name of MDAL driver
|
||||||
* not thread-safe and valid only till next call
|
* not thread-safe and valid only till next call
|
||||||
@ -134,9 +138,13 @@ MDAL_EXPORT const char *MDAL_DR_filters( DriverH driver );
|
|||||||
* Caller must free memory with MDAL_CloseMesh() afterwards
|
* Caller must free memory with MDAL_CloseMesh() afterwards
|
||||||
*/
|
*/
|
||||||
MDAL_EXPORT MeshH MDAL_LoadMesh( const char *meshFile );
|
MDAL_EXPORT MeshH MDAL_LoadMesh( const char *meshFile );
|
||||||
|
|
||||||
//! Closes mesh, frees the memory
|
//! Closes mesh, frees the memory
|
||||||
MDAL_EXPORT void MDAL_CloseMesh( MeshH mesh );
|
MDAL_EXPORT void MDAL_CloseMesh( MeshH mesh );
|
||||||
|
|
||||||
|
//! Saves mesh (only mesh structure) on a file with the specified driver. On error see MDAL_LastStatus for error type.
|
||||||
|
MDAL_EXPORT void MDAL_SaveMesh( MeshH mesh, const char *meshFile, const char *driver );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns mesh projection
|
* Returns mesh projection
|
||||||
* not thread-safe and valid only till next call
|
* not thread-safe and valid only till next call
|
||||||
@ -348,6 +356,11 @@ MDAL_EXPORT bool MDAL_G_isInEditMode( DatasetGroupH group );
|
|||||||
*/
|
*/
|
||||||
MDAL_EXPORT void MDAL_G_closeEditMode( DatasetGroupH group );
|
MDAL_EXPORT void MDAL_G_closeEditMode( DatasetGroupH group );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns reference time for dataset group
|
||||||
|
* If returned value begins with word JULIAN, following number represents date in Julian format
|
||||||
|
*/
|
||||||
|
MDAL_EXPORT const char *MDAL_G_referenceTime( DatasetGroupH group );
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// DATASETS
|
/// DATASETS
|
||||||
|
67
external/mdal/frmts/mdal_2dm.cpp
vendored
67
external/mdal/frmts/mdal_2dm.cpp
vendored
@ -82,7 +82,7 @@ MDAL::Driver2dm::Driver2dm():
|
|||||||
Driver( DRIVER_NAME,
|
Driver( DRIVER_NAME,
|
||||||
"2DM Mesh File",
|
"2DM Mesh File",
|
||||||
"*.2dm",
|
"*.2dm",
|
||||||
Capability::ReadMesh
|
Capability::ReadMesh | Capability::SaveMesh
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ std::unique_ptr<MDAL::Mesh> MDAL::Driver2dm::load( const std::string &meshFile,
|
|||||||
new Mesh2dm(
|
new Mesh2dm(
|
||||||
vertices.size(),
|
vertices.size(),
|
||||||
faces.size(),
|
faces.size(),
|
||||||
4, //maximum quads
|
MAX_VERTICES_PER_FACE_2DM,
|
||||||
computeExtent( vertices ),
|
computeExtent( vertices ),
|
||||||
mMeshFile,
|
mMeshFile,
|
||||||
vertexIDtoIndex
|
vertexIDtoIndex
|
||||||
@ -286,3 +286,66 @@ std::unique_ptr<MDAL::Mesh> MDAL::Driver2dm::load( const std::string &meshFile,
|
|||||||
|
|
||||||
return std::unique_ptr<Mesh>( mesh.release() );
|
return std::unique_ptr<Mesh>( mesh.release() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MDAL::Driver2dm::save( const std::string &uri, MDAL::Mesh *mesh, MDAL_Status *status )
|
||||||
|
{
|
||||||
|
if ( status ) *status = MDAL_Status::None;
|
||||||
|
|
||||||
|
std::ofstream file( uri, std::ofstream::out );
|
||||||
|
|
||||||
|
if ( !file.is_open() )
|
||||||
|
{
|
||||||
|
if ( status ) *status = MDAL_Status::Err_FailToWriteToDisk;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line = "MESH2D";
|
||||||
|
file << line << std::endl;
|
||||||
|
|
||||||
|
//write vertices
|
||||||
|
std::unique_ptr<MDAL::MeshVertexIterator> vertexIterator = mesh->readVertices();
|
||||||
|
double vertex[3];
|
||||||
|
for ( size_t i = 0; i < mesh->verticesCount(); ++i )
|
||||||
|
{
|
||||||
|
vertexIterator->next( 1, vertex );
|
||||||
|
line = "ND ";
|
||||||
|
line.append( std::to_string( i + 1 ) );
|
||||||
|
for ( size_t j = 0; j < 2; ++j )
|
||||||
|
{
|
||||||
|
line.append( " " );
|
||||||
|
line.append( MDAL::coordinateToString( vertex[j] ) );
|
||||||
|
}
|
||||||
|
line.append( " " );
|
||||||
|
line.append( MDAL::doubleToString( vertex[2] ) );
|
||||||
|
|
||||||
|
file << line << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//write faces
|
||||||
|
std::unique_ptr<MDAL::MeshFaceIterator> faceIterator = mesh->readFaces();
|
||||||
|
for ( size_t i = 0; i < mesh->facesCount(); ++i )
|
||||||
|
{
|
||||||
|
int faceOffsets[1];
|
||||||
|
int vertexIndices[4]; //max 4 vertices for a face
|
||||||
|
faceIterator->next( 1, faceOffsets, 4, vertexIndices );
|
||||||
|
|
||||||
|
if ( faceOffsets[0] > 2 && faceOffsets[0] < 5 )
|
||||||
|
{
|
||||||
|
if ( faceOffsets[0] == 3 )
|
||||||
|
line = "E3T ";
|
||||||
|
if ( faceOffsets[0] == 4 )
|
||||||
|
line = "E4Q ";
|
||||||
|
|
||||||
|
line.append( std::to_string( i + 1 ) );
|
||||||
|
|
||||||
|
for ( int j = 0; j < faceOffsets[0]; ++j )
|
||||||
|
{
|
||||||
|
line.append( " " );
|
||||||
|
line.append( std::to_string( vertexIndices[j] + 1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file << line << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
7
external/mdal/frmts/mdal_2dm.hpp
vendored
7
external/mdal/frmts/mdal_2dm.hpp
vendored
@ -14,6 +14,9 @@
|
|||||||
#include "mdal.h"
|
#include "mdal.h"
|
||||||
#include "mdal_driver.hpp"
|
#include "mdal_driver.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_VERTICES_PER_FACE_2DM 4
|
||||||
|
|
||||||
namespace MDAL
|
namespace MDAL
|
||||||
{
|
{
|
||||||
class Mesh2dm: public MemoryMesh
|
class Mesh2dm: public MemoryMesh
|
||||||
@ -80,8 +83,12 @@ namespace MDAL
|
|||||||
~Driver2dm() override;
|
~Driver2dm() override;
|
||||||
Driver2dm *create() override;
|
Driver2dm *create() override;
|
||||||
|
|
||||||
|
int faceVerticesMaximumCount() const override
|
||||||
|
{return MAX_VERTICES_PER_FACE_2DM;}
|
||||||
|
|
||||||
bool canRead( const std::string &uri ) override;
|
bool canRead( const std::string &uri ) override;
|
||||||
std::unique_ptr< Mesh > load( const std::string &meshFile, MDAL_Status *status ) override;
|
std::unique_ptr< Mesh > load( const std::string &meshFile, MDAL_Status *status ) override;
|
||||||
|
void save( const std::string &uri, Mesh *mesh, MDAL_Status *status ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string mMeshFile;
|
std::string mMeshFile;
|
||||||
|
41
external/mdal/frmts/mdal_ascii_dat.cpp
vendored
41
external/mdal/frmts/mdal_ascii_dat.cpp
vendored
@ -142,7 +142,7 @@ void MDAL::DriverAsciiDat::loadNewFormat( std::ifstream &in,
|
|||||||
std::shared_ptr<DatasetGroup> group; // DAT outputs data
|
std::shared_ptr<DatasetGroup> group; // DAT outputs data
|
||||||
std::string groupName( MDAL::baseName( mDatFile ) );
|
std::string groupName( MDAL::baseName( mDatFile ) );
|
||||||
std::string line;
|
std::string line;
|
||||||
|
std::string referenceTime;
|
||||||
// see if it contains face-centered results - supported by BASEMENT
|
// see if it contains face-centered results - supported by BASEMENT
|
||||||
bool faceCentered = false;
|
bool faceCentered = false;
|
||||||
if ( contains( groupName, "_els_" ) )
|
if ( contains( groupName, "_els_" ) )
|
||||||
@ -201,6 +201,7 @@ void MDAL::DriverAsciiDat::loadNewFormat( std::ifstream &in,
|
|||||||
);
|
);
|
||||||
group->setIsScalar( !isVector );
|
group->setIsScalar( !isVector );
|
||||||
group->setIsOnVertices( !faceCentered );
|
group->setIsOnVertices( !faceCentered );
|
||||||
|
group->setReferenceTime( referenceTime );
|
||||||
}
|
}
|
||||||
else if ( cardType == "ENDDS" )
|
else if ( cardType == "ENDDS" )
|
||||||
{
|
{
|
||||||
@ -226,9 +227,24 @@ void MDAL::DriverAsciiDat::loadNewFormat( std::ifstream &in,
|
|||||||
if ( quoteIdx1 != std::string::npos && quoteIdx2 != std::string::npos )
|
if ( quoteIdx1 != std::string::npos && quoteIdx2 != std::string::npos )
|
||||||
group->setName( line.substr( quoteIdx1 + 1, quoteIdx2 - quoteIdx1 - 1 ) );
|
group->setName( line.substr( quoteIdx1 + 1, quoteIdx2 - quoteIdx1 - 1 ) );
|
||||||
}
|
}
|
||||||
|
else if ( cardType == "RT_JULIAN" && items.size() >= 2 )
|
||||||
|
{
|
||||||
|
referenceTime = "JULIAN " + items[1];
|
||||||
|
}
|
||||||
|
else if ( cardType == "TIMEUNITS" && items.size() >= 2 )
|
||||||
|
{
|
||||||
|
if ( !group )
|
||||||
|
{
|
||||||
|
debug( "TIMEUNITS card for no active dataset!" );
|
||||||
|
EXIT_WITH_ERROR( MDAL_Status::Err_UnknownFormat );
|
||||||
|
}
|
||||||
|
|
||||||
|
group->setMetadata( "TIMEUNITS", items[1] );
|
||||||
|
}
|
||||||
else if ( cardType == "TS" && items.size() >= 3 )
|
else if ( cardType == "TS" && items.size() >= 3 )
|
||||||
{
|
{
|
||||||
double t = toDouble( items[2] );
|
double t = toDouble( items[2] );
|
||||||
|
t = convertTimeDataToHours( t, group->getMetadata( "TIMEUNITS" ) );
|
||||||
|
|
||||||
if ( faceCentered )
|
if ( faceCentered )
|
||||||
{
|
{
|
||||||
@ -320,7 +336,7 @@ void MDAL::DriverAsciiDat::readVertexTimestep(
|
|||||||
size_t faceCount = mesh->facesCount();
|
size_t faceCount = mesh->facesCount();
|
||||||
|
|
||||||
std::shared_ptr<MDAL::MemoryDataset> dataset = std::make_shared< MDAL::MemoryDataset >( group.get() );
|
std::shared_ptr<MDAL::MemoryDataset> dataset = std::make_shared< MDAL::MemoryDataset >( group.get() );
|
||||||
dataset->setTime( t / 3600. ); // TODO read TIMEUNITS
|
dataset->setTime( t );
|
||||||
|
|
||||||
int *active = dataset->active();
|
int *active = dataset->active();
|
||||||
// only for new format
|
// only for new format
|
||||||
@ -392,7 +408,7 @@ void MDAL::DriverAsciiDat::readFaceTimestep(
|
|||||||
size_t faceCount = mesh->facesCount();
|
size_t faceCount = mesh->facesCount();
|
||||||
|
|
||||||
std::shared_ptr<MDAL::MemoryDataset> dataset = std::make_shared< MDAL::MemoryDataset >( group.get() );
|
std::shared_ptr<MDAL::MemoryDataset> dataset = std::make_shared< MDAL::MemoryDataset >( group.get() );
|
||||||
dataset->setTime( t / 3600. );
|
dataset->setTime( t );
|
||||||
double *values = dataset->values();
|
double *values = dataset->values();
|
||||||
// TODO: hasStatus
|
// TODO: hasStatus
|
||||||
for ( size_t index = 0; index < faceCount; ++index )
|
for ( size_t index = 0; index < faceCount; ++index )
|
||||||
@ -427,3 +443,22 @@ void MDAL::DriverAsciiDat::readFaceTimestep(
|
|||||||
dataset->setStatistics( MDAL::calculateStatistics( dataset ) );
|
dataset->setStatistics( MDAL::calculateStatistics( dataset ) );
|
||||||
group->datasets.push_back( dataset );
|
group->datasets.push_back( dataset );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double MDAL::DriverAsciiDat::convertTimeDataToHours( double time, const std::string &originalTimeDataUnit ) const
|
||||||
|
{
|
||||||
|
if ( originalTimeDataUnit == "se" || originalTimeDataUnit == "2" || originalTimeDataUnit == "Seconds"
|
||||||
|
|| originalTimeDataUnit.empty() )
|
||||||
|
{
|
||||||
|
time /= 3600.0;
|
||||||
|
}
|
||||||
|
else if ( originalTimeDataUnit == "mi" || originalTimeDataUnit == "1" || originalTimeDataUnit == "Minutes" )
|
||||||
|
{
|
||||||
|
time /= 60.0;
|
||||||
|
}
|
||||||
|
else if ( originalTimeDataUnit == "days" )
|
||||||
|
{
|
||||||
|
time *= 24;
|
||||||
|
}
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
2
external/mdal/frmts/mdal_ascii_dat.hpp
vendored
2
external/mdal/frmts/mdal_ascii_dat.hpp
vendored
@ -84,6 +84,8 @@ namespace MDAL
|
|||||||
bool isVector,
|
bool isVector,
|
||||||
std::ifstream &stream ) const;
|
std::ifstream &stream ) const;
|
||||||
|
|
||||||
|
double convertTimeDataToHours( double time, const std::string &originalTimeDataUnit ) const;
|
||||||
|
|
||||||
std::string mDatFile;
|
std::string mDatFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
67
external/mdal/frmts/mdal_binary_dat.cpp
vendored
67
external/mdal/frmts/mdal_binary_dat.cpp
vendored
@ -33,8 +33,8 @@ static const int CT_NUMCELLS = 180;
|
|||||||
static const int CT_NAME = 190;
|
static const int CT_NAME = 190;
|
||||||
static const int CT_TS = 200;
|
static const int CT_TS = 200;
|
||||||
static const int CT_ENDDS = 210;
|
static const int CT_ENDDS = 210;
|
||||||
//static const int CT_RT_JULIAN = 240;
|
static const int CT_RT_JULIAN = 240;
|
||||||
//static const int CT_TIMEUNITS = 250;
|
static const int CT_TIMEUNITS = 250;
|
||||||
static const int CT_2D_MESHES = 3;
|
static const int CT_2D_MESHES = 3;
|
||||||
static const int CT_FLOAT_SIZE = 4;
|
static const int CT_FLOAT_SIZE = 4;
|
||||||
static const int CF_FLAG_SIZE = 1;
|
static const int CF_FLAG_SIZE = 1;
|
||||||
@ -142,6 +142,9 @@ void MDAL::DriverBinaryDat::load( const std::string &datFile, MDAL::Mesh *mesh,
|
|||||||
int numdata;
|
int numdata;
|
||||||
int numcells;
|
int numcells;
|
||||||
char groupName[40];
|
char groupName[40];
|
||||||
|
double referenceTime;
|
||||||
|
int timeUnit = 0;
|
||||||
|
std::string timeUnitStr;
|
||||||
char istat;
|
char istat;
|
||||||
float time;
|
float time;
|
||||||
|
|
||||||
@ -245,6 +248,44 @@ void MDAL::DriverBinaryDat::load( const std::string &datFile, MDAL::Mesh *mesh,
|
|||||||
groupMax->setName( group->name() + "/Maximums" );
|
groupMax->setName( group->name() + "/Maximums" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CT_RT_JULIAN:
|
||||||
|
// Reference time
|
||||||
|
if ( readIStat( in, sflg, &istat ) )
|
||||||
|
EXIT_WITH_ERROR( MDAL_Status::Err_UnknownFormat );
|
||||||
|
|
||||||
|
if ( read( in, reinterpret_cast< char * >( &time ), 8 ) )
|
||||||
|
EXIT_WITH_ERROR( MDAL_Status::Err_UnknownFormat );
|
||||||
|
|
||||||
|
referenceTime = static_cast<double>( time );
|
||||||
|
group->setReferenceTime( "JULIAN " + std::to_string( referenceTime ) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CT_TIMEUNITS:
|
||||||
|
// Time unit
|
||||||
|
if ( read( in, reinterpret_cast< char * >( &timeUnit ), 4 ) )
|
||||||
|
EXIT_WITH_ERROR( MDAL_Status::Err_UnknownFormat );
|
||||||
|
|
||||||
|
switch ( timeUnit )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
timeUnitStr = "hours";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
timeUnitStr = "minutes";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
timeUnitStr = "seconds";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
timeUnitStr = "days";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
timeUnitStr = "unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
group->setMetadata( "TIMEUNITS", timeUnitStr );
|
||||||
|
break;
|
||||||
|
|
||||||
case CT_TS:
|
case CT_TS:
|
||||||
// Time step!
|
// Time step!
|
||||||
if ( readIStat( in, sflg, &istat ) )
|
if ( readIStat( in, sflg, &istat ) )
|
||||||
@ -254,6 +295,8 @@ void MDAL::DriverBinaryDat::load( const std::string &datFile, MDAL::Mesh *mesh,
|
|||||||
EXIT_WITH_ERROR( MDAL_Status::Err_UnknownFormat );
|
EXIT_WITH_ERROR( MDAL_Status::Err_UnknownFormat );
|
||||||
|
|
||||||
double t = static_cast<double>( time );
|
double t = static_cast<double>( time );
|
||||||
|
t = convertTimeDataToHours( t, timeUnit );
|
||||||
|
|
||||||
if ( readVertexTimestep( mesh, group, groupMax, t, istat, sflg, in ) )
|
if ( readVertexTimestep( mesh, group, groupMax, t, istat, sflg, in ) )
|
||||||
EXIT_WITH_ERROR( MDAL_Status::Err_UnknownFormat );
|
EXIT_WITH_ERROR( MDAL_Status::Err_UnknownFormat );
|
||||||
|
|
||||||
@ -461,3 +504,23 @@ bool MDAL::DriverBinaryDat::persist( MDAL::DatasetGroup *group )
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double MDAL::DriverBinaryDat::convertTimeDataToHours( double time, int originalTimeDataUnit )
|
||||||
|
{
|
||||||
|
switch ( originalTimeDataUnit )
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
time /= 60.0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
time /= 3600.0;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
time *= 24;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
1
external/mdal/frmts/mdal_binary_dat.hpp
vendored
1
external/mdal/frmts/mdal_binary_dat.hpp
vendored
@ -40,6 +40,7 @@ namespace MDAL
|
|||||||
int sflg,
|
int sflg,
|
||||||
std::ifstream &in );
|
std::ifstream &in );
|
||||||
|
|
||||||
|
double convertTimeDataToHours( double time, int originalTimeDataUnit );
|
||||||
std::string mDatFile;
|
std::string mDatFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
69
external/mdal/frmts/mdal_cf.cpp
vendored
69
external/mdal/frmts/mdal_cf.cpp
vendored
@ -71,9 +71,25 @@ MDAL::cfdataset_info_map MDAL::DriverCF::parseDatasetGroupInfo()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nTimesteps = mDimensions.size( CFDimensions::Time );
|
/*UGRID convention says "The order of dimensions on a data variable is arbitrary",
|
||||||
|
*So time dimension is not necessary the first dimension, event if the convention recommands it.
|
||||||
|
*And prevent that any of the the two dimensions is not time dimension
|
||||||
|
*/
|
||||||
|
if ( mDimensions.type( dimids[0] ) == CFDimensions::Time )
|
||||||
|
{
|
||||||
dimid = dimids[1];
|
dimid = dimids[1];
|
||||||
}
|
}
|
||||||
|
else if ( mDimensions.type( dimids[1] ) == CFDimensions::Time )
|
||||||
|
{
|
||||||
|
dimid = dimids[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
nTimesteps = mDimensions.size( CFDimensions::Time );
|
||||||
|
}
|
||||||
|
|
||||||
if ( !mDimensions.isDatasetType( mDimensions.type( dimid ) ) )
|
if ( !mDimensions.isDatasetType( mDimensions.type( dimid ) ) )
|
||||||
continue;
|
continue;
|
||||||
@ -169,6 +185,34 @@ std::shared_ptr<MDAL::Dataset> MDAL::DriverCF::createFace2DDataset( std::shared_
|
|||||||
return dataset;
|
return dataset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MDAL::Dataset> MDAL::DriverCF::createVertex2DDataset( std::shared_ptr<MDAL::DatasetGroup> group,
|
||||||
|
size_t ts, const MDAL::CFDatasetGroupInfo &dsi,
|
||||||
|
const std::vector<double> &vals_x,
|
||||||
|
const std::vector<double> &vals_y,
|
||||||
|
double fill_val_x, double fill_val_y )
|
||||||
|
{
|
||||||
|
assert( dsi.outputType == CFDimensions::Vertex2D );
|
||||||
|
size_t nVertices2D = mDimensions.size( CFDimensions::Vertex2D );
|
||||||
|
|
||||||
|
std::shared_ptr<MDAL::MemoryDataset> dataset = std::make_shared<MDAL::MemoryDataset>( group.get() );
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < nVertices2D; ++i )
|
||||||
|
{
|
||||||
|
size_t idx = ts * nVertices2D + i;
|
||||||
|
populate_vals( dsi.is_vector,
|
||||||
|
dataset->values(),
|
||||||
|
i,
|
||||||
|
vals_x,
|
||||||
|
vals_y,
|
||||||
|
idx,
|
||||||
|
fill_val_x,
|
||||||
|
fill_val_y );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataset;
|
||||||
|
}
|
||||||
|
|
||||||
void MDAL::DriverCF::addDatasetGroups( MDAL::Mesh *mesh, const std::vector<double> ×, const MDAL::cfdataset_info_map &dsinfo_map )
|
void MDAL::DriverCF::addDatasetGroups( MDAL::Mesh *mesh, const std::vector<double> ×, const MDAL::cfdataset_info_map &dsinfo_map )
|
||||||
{
|
{
|
||||||
/* PHASE 2 - add dataset groups */
|
/* PHASE 2 - add dataset groups */
|
||||||
@ -183,7 +227,16 @@ void MDAL::DriverCF::addDatasetGroups( MDAL::Mesh *mesh, const std::vector<doubl
|
|||||||
dsi.name
|
dsi.name
|
||||||
);
|
);
|
||||||
group->setIsScalar( !dsi.is_vector );
|
group->setIsScalar( !dsi.is_vector );
|
||||||
|
|
||||||
|
if ( dsi.outputType == CFDimensions::Vertex2D )
|
||||||
|
group->setIsOnVertices( true );
|
||||||
|
else if ( dsi.outputType == CFDimensions::Face2D )
|
||||||
group->setIsOnVertices( false );
|
group->setIsOnVertices( false );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// unsupported
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// read X data
|
// read X data
|
||||||
double fill_val_x = mNcFile.getFillValue( dsi.ncid_x );
|
double fill_val_x = mNcFile.getFillValue( dsi.ncid_x );
|
||||||
@ -209,6 +262,13 @@ void MDAL::DriverCF::addDatasetGroups( MDAL::Mesh *mesh, const std::vector<doubl
|
|||||||
if ( dsi.outputType == CFDimensions::Face2D )
|
if ( dsi.outputType == CFDimensions::Face2D )
|
||||||
{
|
{
|
||||||
dataset = createFace2DDataset( group, ts, dsi, vals_x, vals_y, fill_val_x, fill_val_y );
|
dataset = createFace2DDataset( group, ts, dsi, vals_x, vals_y, fill_val_x, fill_val_y );
|
||||||
|
}
|
||||||
|
else // Vertex2D
|
||||||
|
{
|
||||||
|
dataset = createVertex2DDataset( group, ts, dsi, vals_x, vals_y, fill_val_x, fill_val_y );
|
||||||
|
}
|
||||||
|
if ( dataset )
|
||||||
|
{
|
||||||
dataset->setTime( time );
|
dataset->setTime( time );
|
||||||
dataset->setStatistics( MDAL::calculateStatistics( dataset ) );
|
dataset->setStatistics( MDAL::calculateStatistics( dataset ) );
|
||||||
group->datasets.push_back( dataset );
|
group->datasets.push_back( dataset );
|
||||||
@ -228,6 +288,13 @@ void MDAL::DriverCF::parseTime( std::vector<double> × )
|
|||||||
{
|
{
|
||||||
|
|
||||||
size_t nTimesteps = mDimensions.size( CFDimensions::Time );
|
size_t nTimesteps = mDimensions.size( CFDimensions::Time );
|
||||||
|
if ( 0 == nTimesteps )
|
||||||
|
{
|
||||||
|
//if no time dimension is present creates only one time step to store the potential time-independent variable
|
||||||
|
nTimesteps = 1;
|
||||||
|
times = std::vector<double>( 1, 0 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
times = mNcFile.readDoubleArr( "time", nTimesteps );
|
times = mNcFile.readDoubleArr( "time", nTimesteps );
|
||||||
std::string units = mNcFile.getAttrStr( "time", "units" );
|
std::string units = mNcFile.getAttrStr( "time", "units" );
|
||||||
double div_by = MDAL::parseTimeUnits( units );
|
double div_by = MDAL::parseTimeUnits( units );
|
||||||
|
8
external/mdal/frmts/mdal_cf.hpp
vendored
8
external/mdal/frmts/mdal_cf.hpp
vendored
@ -94,6 +94,14 @@ namespace MDAL
|
|||||||
const std::vector<double> &vals_y,
|
const std::vector<double> &vals_y,
|
||||||
double fill_val_x, double fill_val_y );
|
double fill_val_x, double fill_val_y );
|
||||||
|
|
||||||
|
std::shared_ptr<MDAL::Dataset> createVertex2DDataset(
|
||||||
|
std::shared_ptr<MDAL::DatasetGroup> group,
|
||||||
|
size_t ts,
|
||||||
|
const MDAL::CFDatasetGroupInfo &dsi,
|
||||||
|
const std::vector<double> &vals_x,
|
||||||
|
const std::vector<double> &vals_y,
|
||||||
|
double fill_val_x, double fill_val_y );
|
||||||
|
|
||||||
void addDatasetGroups( Mesh *mesh,
|
void addDatasetGroups( Mesh *mesh,
|
||||||
const std::vector<double> ×,
|
const std::vector<double> ×,
|
||||||
const cfdataset_info_map &dsinfo_map );
|
const cfdataset_info_map &dsinfo_map );
|
||||||
|
12
external/mdal/frmts/mdal_driver.cpp
vendored
12
external/mdal/frmts/mdal_driver.cpp
vendored
@ -42,6 +42,11 @@ bool MDAL::Driver::hasCapability( MDAL::Capability capability ) const
|
|||||||
return capability == ( mCapabilityFlags & capability );
|
return capability == ( mCapabilityFlags & capability );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MDAL::Driver::faceVerticesMaximumCount() const
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr< MDAL::Mesh > MDAL::Driver::load( const std::string &uri, MDAL_Status *status )
|
std::unique_ptr< MDAL::Mesh > MDAL::Driver::load( const std::string &uri, MDAL_Status *status )
|
||||||
{
|
{
|
||||||
MDAL_UNUSED( uri );
|
MDAL_UNUSED( uri );
|
||||||
@ -57,6 +62,13 @@ void MDAL::Driver::load( const std::string &uri, Mesh *mesh, MDAL_Status *status
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MDAL::Driver::save( const std::string &uri, MDAL::Mesh *mesh, MDAL_Status *status )
|
||||||
|
{
|
||||||
|
MDAL_UNUSED( uri );
|
||||||
|
MDAL_UNUSED( mesh );
|
||||||
|
MDAL_UNUSED( status );
|
||||||
|
}
|
||||||
|
|
||||||
void MDAL::Driver::createDatasetGroup( MDAL::Mesh *mesh, const std::string &groupName, bool isOnVertices, bool hasScalarData, const std::string &datasetGroupFile )
|
void MDAL::Driver::createDatasetGroup( MDAL::Mesh *mesh, const std::string &groupName, bool isOnVertices, bool hasScalarData, const std::string &datasetGroupFile )
|
||||||
{
|
{
|
||||||
std::shared_ptr<MDAL::DatasetGroup> grp(
|
std::shared_ptr<MDAL::DatasetGroup> grp(
|
||||||
|
7
external/mdal/frmts/mdal_driver.hpp
vendored
7
external/mdal/frmts/mdal_driver.hpp
vendored
@ -18,6 +18,7 @@ namespace MDAL
|
|||||||
ReadMesh = 1 << 0, //! Can read mesh and all datasets stored in the mesh file
|
ReadMesh = 1 << 0, //! Can read mesh and all datasets stored in the mesh file
|
||||||
ReadDatasets = 1 << 1, //! Can read only datasets (groups) from existing mesh
|
ReadDatasets = 1 << 1, //! Can read only datasets (groups) from existing mesh
|
||||||
WriteDatasets = 1 << 2, //! Can write datasets (groups)
|
WriteDatasets = 1 << 2, //! Can write datasets (groups)
|
||||||
|
SaveMesh = 1 << 3, //! Can save the mesh
|
||||||
};
|
};
|
||||||
|
|
||||||
class Driver
|
class Driver
|
||||||
@ -39,11 +40,17 @@ namespace MDAL
|
|||||||
|
|
||||||
virtual bool canRead( const std::string &uri ) = 0;
|
virtual bool canRead( const std::string &uri ) = 0;
|
||||||
|
|
||||||
|
//! returns the maximum vertices per face
|
||||||
|
virtual int faceVerticesMaximumCount() const;
|
||||||
|
|
||||||
// loads mesh
|
// loads mesh
|
||||||
virtual std::unique_ptr< Mesh > load( const std::string &uri, MDAL_Status *status );
|
virtual std::unique_ptr< Mesh > load( const std::string &uri, MDAL_Status *status );
|
||||||
// loads datasets
|
// loads datasets
|
||||||
virtual void load( const std::string &uri, Mesh *mesh, MDAL_Status *status );
|
virtual void load( const std::string &uri, Mesh *mesh, MDAL_Status *status );
|
||||||
|
|
||||||
|
// save mesh
|
||||||
|
virtual void save( const std::string &uri, Mesh *mesh, MDAL_Status *status );
|
||||||
|
|
||||||
// create new dataset group
|
// create new dataset group
|
||||||
virtual void createDatasetGroup(
|
virtual void createDatasetGroup(
|
||||||
Mesh *mesh,
|
Mesh *mesh,
|
||||||
|
300
external/mdal/frmts/mdal_esri_tin.cpp
vendored
Normal file
300
external/mdal/frmts/mdal_esri_tin.cpp
vendored
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
/*
|
||||||
|
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||||
|
Copyright (C) 2019 Vincent Cloarec (vcloarec at gmail dot com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mdal_esri_tin.hpp"
|
||||||
|
|
||||||
|
MDAL::DriverEsriTin::DriverEsriTin(): Driver( "ESRI_TIN",
|
||||||
|
"Esri TIN",
|
||||||
|
"*.adf",
|
||||||
|
Capability::ReadMesh )
|
||||||
|
{}
|
||||||
|
|
||||||
|
MDAL::Driver *MDAL::DriverEsriTin::create()
|
||||||
|
{
|
||||||
|
return new DriverEsriTin();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<MDAL::Mesh> MDAL::DriverEsriTin::load( const std::string &uri, MDAL_Status *status )
|
||||||
|
{
|
||||||
|
if ( status ) *status = MDAL_Status::None;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::list<int> superpointIndexes;
|
||||||
|
Vertices vertices;
|
||||||
|
Faces faces;
|
||||||
|
|
||||||
|
readSuperpoints( uri, superpointIndexes );
|
||||||
|
populateVertices( uri, vertices, superpointIndexes );
|
||||||
|
populateFaces( uri, faces, superpointIndexes );
|
||||||
|
|
||||||
|
std::unique_ptr< MemoryMesh > mesh(
|
||||||
|
new MemoryMesh(
|
||||||
|
name(),
|
||||||
|
vertices.size(),
|
||||||
|
faces.size(),
|
||||||
|
3,
|
||||||
|
computeExtent( vertices ),
|
||||||
|
uri
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
mesh->faces = std::move( faces );
|
||||||
|
mesh->vertices = std::move( vertices );
|
||||||
|
|
||||||
|
addBedElevationDatasetGroup( mesh.get(), mesh->vertices );
|
||||||
|
mesh->datasetGroups.back()->setName( "Altitude" );
|
||||||
|
|
||||||
|
std::string crs = getCrsWkt( uri );
|
||||||
|
if ( ! crs.empty() )
|
||||||
|
mesh->setSourceCrsFromWKT( crs );
|
||||||
|
|
||||||
|
return std::unique_ptr<Mesh>( mesh.release() );
|
||||||
|
}
|
||||||
|
catch ( MDAL_Status error )
|
||||||
|
{
|
||||||
|
if ( status ) *status = ( error );
|
||||||
|
return std::unique_ptr<Mesh>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MDAL::DriverEsriTin::canRead( const std::string &uri )
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string zFileName = zFile( uri );
|
||||||
|
std::string faceFileName = faceFile( uri );
|
||||||
|
|
||||||
|
std::ifstream xyIn( xyFile( uri ), std::ifstream::in | std::ifstream::binary );
|
||||||
|
if ( ! xyIn.is_open() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::ifstream zIn( zFile( uri ), std::ifstream::in | std::ifstream::binary );
|
||||||
|
if ( ! zIn.is_open() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::ifstream faceIn( faceFile( uri ), std::ifstream::in | std::ifstream::binary );
|
||||||
|
if ( ! faceIn.is_open() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::ifstream hullIn( hullFile( uri ), std::ifstream::in | std::ifstream::binary );
|
||||||
|
if ( ! hullIn.is_open() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MDAL::DriverEsriTin::xyFile( const std::string &uri ) const
|
||||||
|
{
|
||||||
|
return pathJoin( dirName( uri ), "tnxy.adf" );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MDAL::DriverEsriTin::zFile( const std::string &uri ) const
|
||||||
|
{
|
||||||
|
return pathJoin( dirName( uri ), "tnz.adf" );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MDAL::DriverEsriTin::faceFile( const std::string &uri ) const
|
||||||
|
{
|
||||||
|
return pathJoin( dirName( uri ), "tnod.adf" );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MDAL::DriverEsriTin::mskFile( const std::string &uri ) const
|
||||||
|
{
|
||||||
|
return pathJoin( dirName( uri ), "tmsk.adf" );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MDAL::DriverEsriTin::msxFile( const std::string &uri ) const
|
||||||
|
{
|
||||||
|
return pathJoin( dirName( uri ), "tmsx.adf" );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MDAL::DriverEsriTin::hullFile( const std::string &uri ) const
|
||||||
|
{
|
||||||
|
return pathJoin( dirName( uri ), "thul.adf" );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MDAL::DriverEsriTin::crsFile( const std::string &uri ) const
|
||||||
|
{
|
||||||
|
return pathJoin( dirName( uri ), "prj.adf" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void MDAL::DriverEsriTin::readSuperpoints( const std::string &uri, std::list<int> &superpointsIndexes ) const
|
||||||
|
{
|
||||||
|
superpointsIndexes.clear();
|
||||||
|
bool isNativeLittleEndian = MDAL::isNativeLittleEndian();
|
||||||
|
std::ifstream inHull( hullFile( uri ), std::ifstream::in | std::ifstream::binary );
|
||||||
|
|
||||||
|
int32_t index;
|
||||||
|
while ( readValue( index, inHull, isNativeLittleEndian ) && index != -1 )
|
||||||
|
superpointsIndexes.push_back( index );
|
||||||
|
|
||||||
|
superpointsIndexes.sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MDAL::DriverEsriTin::getTinName( const std::string &uri ) const
|
||||||
|
{
|
||||||
|
std::string tinName = uri;
|
||||||
|
size_t last_slash_idx = tinName.find_last_of( "\\/" );
|
||||||
|
|
||||||
|
if ( last_slash_idx == std::string::npos )
|
||||||
|
return "";
|
||||||
|
|
||||||
|
tinName.erase( last_slash_idx, tinName.size() - last_slash_idx );
|
||||||
|
last_slash_idx = tinName.find_last_of( "\\/" );
|
||||||
|
|
||||||
|
if ( last_slash_idx == std::string::npos )
|
||||||
|
return "";
|
||||||
|
|
||||||
|
tinName.erase( 0, last_slash_idx + 1 );
|
||||||
|
|
||||||
|
return tinName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MDAL::DriverEsriTin::populateVertices( const std::string &uri, MDAL::Vertices &vertices, const std::list<int> &superpointIndexes ) const
|
||||||
|
{
|
||||||
|
//first, read the (x,y) coordinates
|
||||||
|
|
||||||
|
bool isNativeLittleEndian = MDAL::isNativeLittleEndian();
|
||||||
|
std::ifstream inXY( xyFile( uri ), std::ifstream::in | std::ifstream::binary );
|
||||||
|
std::ifstream inZ( zFile( uri ), std::ifstream::in | std::ifstream::binary );
|
||||||
|
|
||||||
|
if ( ! inXY.is_open() )
|
||||||
|
throw MDAL_Status::Err_FileNotFound;
|
||||||
|
|
||||||
|
if ( ! inZ.is_open() )
|
||||||
|
throw MDAL_Status::Err_FileNotFound;
|
||||||
|
|
||||||
|
int fileIndex = 1;
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
Vertex vert;
|
||||||
|
|
||||||
|
if ( !readValue( vert.x, inXY, isNativeLittleEndian ) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ( !readValue( vert.y, inXY, isNativeLittleEndian ) )
|
||||||
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
|
||||||
|
float zValue;
|
||||||
|
if ( !readValue( zValue, inZ, isNativeLittleEndian ) )
|
||||||
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
vert.z = double( zValue );
|
||||||
|
|
||||||
|
if ( correctedIndex( fileIndex, superpointIndexes ) >= 0 ) //store the vertex only if it is not a superpoint
|
||||||
|
vertices.push_back( vert );
|
||||||
|
fileIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
inXY.close();
|
||||||
|
inZ.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MDAL::DriverEsriTin::populateFaces( const std::string &uri, MDAL::Faces &faces, const std::list<int> &superpointIndexes ) const
|
||||||
|
{
|
||||||
|
bool isNativeLittleEndian = MDAL::isNativeLittleEndian();
|
||||||
|
std::ifstream inFaces( faceFile( uri ), std::ifstream::in | std::ifstream::binary );
|
||||||
|
std::ifstream inMsk( mskFile( uri ), std::ifstream::in | std::ifstream::binary );
|
||||||
|
std::ifstream inMsx( msxFile( uri ), std::ifstream::in | std::ifstream::binary );
|
||||||
|
|
||||||
|
if ( ! inFaces.is_open() )
|
||||||
|
throw MDAL_Status::Err_FileNotFound;
|
||||||
|
if ( ! inMsk.is_open() )
|
||||||
|
throw MDAL_Status::Err_FileNotFound;
|
||||||
|
if ( ! inMsx.is_open() )
|
||||||
|
throw MDAL_Status::Err_FileNotFound;
|
||||||
|
|
||||||
|
//Find the beginning of data in mskFile
|
||||||
|
inMsx.seekg( -4, std::ios::end );
|
||||||
|
int32_t mskBegin;
|
||||||
|
if ( ! readValue( mskBegin, inMsx, true ) )
|
||||||
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
|
||||||
|
//read information in mskFile
|
||||||
|
inMsk.seekg( -mskBegin * 2, std::ios::end );
|
||||||
|
int32_t maskIntergerCount;
|
||||||
|
if ( ! readValue( maskIntergerCount, inMsk, true ) )
|
||||||
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
inMsk.ignore( 4 ); //unused 4 bytes
|
||||||
|
int32_t maskBitsCount;
|
||||||
|
if ( ! readValue( maskBitsCount, inMsk, true ) )
|
||||||
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
|
||||||
|
int c = 0;
|
||||||
|
int32_t maskInt = 0;
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
//read mask file
|
||||||
|
if ( c % 32 == 0 && c < maskBitsCount ) //first bit in the mask array have to be used-->read next maskInt
|
||||||
|
if ( ! readValue( maskInt, inMsk, true ) )
|
||||||
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
|
||||||
|
Face f;
|
||||||
|
for ( int i = 0; i < 3; ++i )
|
||||||
|
{
|
||||||
|
int32_t index;
|
||||||
|
if ( ! readValue( index, inFaces, isNativeLittleEndian ) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
index = correctedIndex( index, superpointIndexes );
|
||||||
|
|
||||||
|
f.push_back( static_cast<size_t>( index ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( f.size() == 0 ) //that's mean this is the end of the file
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ( f.size() < 3 ) //that's mean the face is not complete
|
||||||
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
|
||||||
|
//exclude masked face
|
||||||
|
if ( !( maskInt & 0x01 ) )
|
||||||
|
faces.push_back( f );
|
||||||
|
|
||||||
|
c++;
|
||||||
|
maskInt = maskInt >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inFaces.close();
|
||||||
|
inMsk.close();
|
||||||
|
inMsx.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MDAL::DriverEsriTin::getCrsWkt( const std::string &uri ) const
|
||||||
|
{
|
||||||
|
std::ifstream inCRS( crsFile( uri ), std::ifstream::in );
|
||||||
|
if ( ! inCRS.is_open() )
|
||||||
|
return std::string();
|
||||||
|
|
||||||
|
std::string crsWkt;
|
||||||
|
std::getline( inCRS, crsWkt );
|
||||||
|
|
||||||
|
if ( crsWkt == "{B286C06B-0879-11D2-AACA-00C04FA33C20}" ) //com class id of the esri UnknownCoordinateSystem class
|
||||||
|
crsWkt = "";
|
||||||
|
|
||||||
|
return crsWkt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MDAL::DriverEsriTin::correctedIndex( int i, const std::list<int> &superPointsIndexes ) const
|
||||||
|
{
|
||||||
|
//usualy i is bigger than the biggest superpoint's index
|
||||||
|
if ( i > superPointsIndexes.back() )
|
||||||
|
return i - int( superPointsIndexes.size() ) - 1;
|
||||||
|
|
||||||
|
//correction of index depending of the position of the superpoints
|
||||||
|
int correctedIndex = i - 1;
|
||||||
|
for ( auto si : superPointsIndexes )
|
||||||
|
{
|
||||||
|
if ( i == si )
|
||||||
|
return -1; //return -1 if the index is associated with superpoint
|
||||||
|
else if ( i > si )
|
||||||
|
{
|
||||||
|
correctedIndex--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return correctedIndex;
|
||||||
|
}
|
100
external/mdal/frmts/mdal_esri_tin.hpp
vendored
Normal file
100
external/mdal/frmts/mdal_esri_tin.hpp
vendored
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||||
|
Copyright (C) 2019 Vincent Cloarec (vcloarec at gmail dot com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MDAL_ESRI_TIN_H
|
||||||
|
#define MDAL_ESRI_TIN_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
#include <memory>
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "mdal_data_model.hpp"
|
||||||
|
#include "mdal.h"
|
||||||
|
#include "mdal_driver.hpp"
|
||||||
|
#include "mdal_utils.hpp"
|
||||||
|
|
||||||
|
namespace MDAL
|
||||||
|
{
|
||||||
|
|
||||||
|
/** *********************************************
|
||||||
|
* Structure of files
|
||||||
|
* https://en.wikipedia.org/wiki/Esri_TIN
|
||||||
|
************************************************
|
||||||
|
* thul.adf
|
||||||
|
*
|
||||||
|
* file containing only int (big-endianness)
|
||||||
|
* first, list of superpoint indexes (infinity point to North, South East and West)
|
||||||
|
* used by ArcGIS but unused here
|
||||||
|
* This list finished with value -1
|
||||||
|
* Then indexes of the outer boundary indexes or inner boundary indexes (holes)
|
||||||
|
* Those list are separated with value 0
|
||||||
|
*
|
||||||
|
* ***************************************
|
||||||
|
* tnxy.adf
|
||||||
|
*
|
||||||
|
* vertices position X,Y : for each value 8 bytes : double with big-endianness
|
||||||
|
*
|
||||||
|
* ***************************************
|
||||||
|
* tnz.adf : z value of each vertices
|
||||||
|
*
|
||||||
|
* vertices Z value: for each value 4 bytes : float with big endianness
|
||||||
|
*
|
||||||
|
* ***************************************
|
||||||
|
* tnod.adf : faces (triangles) of the TIN
|
||||||
|
*
|
||||||
|
* indexes of the 3 vertices for each faces (int32 big-endianness)
|
||||||
|
*
|
||||||
|
* ***************************************
|
||||||
|
* tmsk.adf and tmsx.adf
|
||||||
|
*
|
||||||
|
* files used to store information about masked faces. Those faces are not displayed
|
||||||
|
*
|
||||||
|
*****************************************
|
||||||
|
* prj.adf
|
||||||
|
*
|
||||||
|
* text file containing the WKT CRS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
class DriverEsriTin: public Driver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DriverEsriTin();
|
||||||
|
~DriverEsriTin() override {}
|
||||||
|
|
||||||
|
Driver *create() override;
|
||||||
|
|
||||||
|
virtual std::unique_ptr< Mesh > load( const std::string &uri, MDAL_Status *status ) override;
|
||||||
|
|
||||||
|
bool canRead( const std::string &uri ) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string xyFile( const std::string &uri ) const;
|
||||||
|
std::string zFile( const std::string &uri ) const;
|
||||||
|
std::string faceFile( const std::string &uri ) const;
|
||||||
|
std::string mskFile( const std::string &uri ) const;
|
||||||
|
std::string msxFile( const std::string &uri ) const;
|
||||||
|
std::string hullFile( const std::string &uri ) const;
|
||||||
|
std::string crsFile( const std::string &uri ) const;
|
||||||
|
|
||||||
|
void readSuperpoints( const std::string &uri, std::list<int> &superpointsIndexes ) const;
|
||||||
|
void populateVertices( const std::string &uri, Vertices &vertices, const std::list<int> &superpointIndexes ) const;
|
||||||
|
void populateFaces( const std::string &uri, Faces &faces, const std::list<int> &superpointIndexes ) const;
|
||||||
|
|
||||||
|
std::string getCrsWkt( const std::string &uri ) const;
|
||||||
|
std::string getTinName( const std::string &uri ) const;
|
||||||
|
|
||||||
|
// correction of vertex index because indexing in ESRI TIN files begins with 1 and to take account superpoints position
|
||||||
|
// return -1 if i is the index of a superpoint
|
||||||
|
int correctedIndex( int i, const std::list<int> &superPointsIndexes ) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MDAL_ESRI_TIN_H
|
14
external/mdal/frmts/mdal_hdf5.cpp
vendored
14
external/mdal/frmts/mdal_hdf5.cpp
vendored
@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mdal_hdf5.hpp"
|
#include "mdal_hdf5.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
HdfFile::HdfFile( const std::string &path )
|
HdfFile::HdfFile( const std::string &path )
|
||||||
@ -68,17 +69,21 @@ hid_t HdfAttribute::id() const { return d->id; }
|
|||||||
|
|
||||||
std::string HdfAttribute::readString() const
|
std::string HdfAttribute::readString() const
|
||||||
{
|
{
|
||||||
char name[HDF_MAX_NAME];
|
hid_t datatype = H5Aget_type( id() );
|
||||||
hid_t datatype = H5Tcopy( H5T_C_S1 );
|
char name[HDF_MAX_NAME + 1];
|
||||||
H5Tset_size( datatype, HDF_MAX_NAME );
|
std::memset( name, '\0', HDF_MAX_NAME + 1 );
|
||||||
herr_t status = H5Aread( d->id, datatype, name );
|
herr_t status = H5Aread( d->id, datatype, name );
|
||||||
if ( status < 0 )
|
if ( status < 0 )
|
||||||
{
|
{
|
||||||
//MDAL::debug("Failed to read data!");
|
//MDAL::debug("Failed to read data!");
|
||||||
|
H5Tclose( datatype );
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
H5Tclose( datatype );
|
H5Tclose( datatype );
|
||||||
return std::string( name );
|
std::string res( name );
|
||||||
|
res = MDAL::trim( res );
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
HdfDataset::HdfDataset( hid_t file, const std::string &path )
|
HdfDataset::HdfDataset( hid_t file, const std::string &path )
|
||||||
@ -189,7 +194,6 @@ std::string HdfDataset::readString() const
|
|||||||
return std::string( name );
|
return std::string( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HdfDataspace::HdfDataspace( const std::vector<hsize_t> &dims )
|
HdfDataspace::HdfDataspace( const std::vector<hsize_t> &dims )
|
||||||
: d( std::make_shared< Handle >( H5Screate_simple(
|
: d( std::make_shared< Handle >( H5Screate_simple(
|
||||||
static_cast<int>( dims.size() ),
|
static_cast<int>( dims.size() ),
|
||||||
|
11
external/mdal/frmts/mdal_hdf5.hpp
vendored
11
external/mdal/frmts/mdal_hdf5.hpp
vendored
@ -97,7 +97,6 @@ class HdfGroup
|
|||||||
inline HdfDataset dataset( const std::string &dsName ) const;
|
inline HdfDataset dataset( const std::string &dsName ) const;
|
||||||
inline HdfAttribute attribute( const std::string &attr_name ) const;
|
inline HdfAttribute attribute( const std::string &attr_name ) const;
|
||||||
inline bool pathExists( const std::string &path ) const;
|
inline bool pathExists( const std::string &path ) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<std::string> objects( H5G_obj_t type ) const;
|
std::vector<std::string> objects( H5G_obj_t type ) const;
|
||||||
|
|
||||||
@ -176,6 +175,8 @@ class HdfDataset
|
|||||||
std::vector<double> readArrayDouble( const std::vector<hsize_t> offsets, const std::vector<hsize_t> counts ) const;
|
std::vector<double> readArrayDouble( const std::vector<hsize_t> offsets, const std::vector<hsize_t> counts ) const;
|
||||||
std::vector<int> readArrayInt( const std::vector<hsize_t> offsets, const std::vector<hsize_t> counts ) const;
|
std::vector<int> readArrayInt( const std::vector<hsize_t> offsets, const std::vector<hsize_t> counts ) const;
|
||||||
|
|
||||||
|
inline bool hasAttribute( const std::string &attr_name ) const;
|
||||||
|
inline HdfAttribute attribute( const std::string &attr_name ) const;
|
||||||
|
|
||||||
template <typename T> std::vector<T> readArray( hid_t mem_type_id ) const
|
template <typename T> std::vector<T> readArray( hid_t mem_type_id ) const
|
||||||
{
|
{
|
||||||
@ -233,10 +234,18 @@ inline HdfGroup HdfGroup::group( const std::string &groupName ) const { return H
|
|||||||
|
|
||||||
inline HdfDataset HdfGroup::dataset( const std::string &dsName ) const { return HdfDataset( file_id(), childPath( dsName ) ); }
|
inline HdfDataset HdfGroup::dataset( const std::string &dsName ) const { return HdfDataset( file_id(), childPath( dsName ) ); }
|
||||||
|
|
||||||
|
inline bool HdfDataset::hasAttribute( const std::string &attr_name ) const
|
||||||
|
{
|
||||||
|
htri_t res = H5Aexists( d->id, attr_name.c_str() );
|
||||||
|
return res > 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
inline HdfAttribute HdfFile::attribute( const std::string &attr_name ) const { return HdfAttribute( d->id, attr_name ); }
|
inline HdfAttribute HdfFile::attribute( const std::string &attr_name ) const { return HdfAttribute( d->id, attr_name ); }
|
||||||
|
|
||||||
inline HdfAttribute HdfGroup::attribute( const std::string &attr_name ) const { return HdfAttribute( d->id, attr_name ); }
|
inline HdfAttribute HdfGroup::attribute( const std::string &attr_name ) const { return HdfAttribute( d->id, attr_name ); }
|
||||||
|
|
||||||
|
inline HdfAttribute HdfDataset::attribute( const std::string &attr_name ) const { return HdfAttribute( d->id, attr_name ); }
|
||||||
|
|
||||||
inline bool HdfFile::pathExists( const std::string &path ) const { return H5Lexists( d->id, path.c_str(), H5P_DEFAULT ) > 0; }
|
inline bool HdfFile::pathExists( const std::string &path ) const { return H5Lexists( d->id, path.c_str(), H5P_DEFAULT ) > 0; }
|
||||||
|
|
||||||
inline bool HdfGroup::pathExists( const std::string &path ) const { return H5Lexists( d->id, path.c_str(), H5P_DEFAULT ) > 0; }
|
inline bool HdfGroup::pathExists( const std::string &path ) const { return H5Lexists( d->id, path.c_str(), H5P_DEFAULT ) > 0; }
|
||||||
|
98
external/mdal/frmts/mdal_hec2d.cpp
vendored
98
external/mdal/frmts/mdal_hec2d.cpp
vendored
@ -43,7 +43,6 @@ static HdfDataset openHdfDataset( const HdfGroup &hdfGroup, const std::string &n
|
|||||||
return dsFileType;
|
return dsFileType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static std::string openHdfAttribute( const HdfFile &hdfFile, const std::string &name )
|
static std::string openHdfAttribute( const HdfFile &hdfFile, const std::string &name )
|
||||||
{
|
{
|
||||||
HdfAttribute attr = hdfFile.attribute( name );
|
HdfAttribute attr = hdfFile.attribute( name );
|
||||||
@ -51,6 +50,13 @@ static std::string openHdfAttribute( const HdfFile &hdfFile, const std::string &
|
|||||||
return attr.readString();
|
return attr.readString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string openHdfAttribute( const HdfDataset &hdfDataset, const std::string &name )
|
||||||
|
{
|
||||||
|
HdfAttribute attr = hdfDataset.attribute( name );
|
||||||
|
if ( !attr.isValid() ) throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
return attr.readString();
|
||||||
|
}
|
||||||
|
|
||||||
static HdfGroup getBaseOutputGroup( const HdfFile &hdfFile )
|
static HdfGroup getBaseOutputGroup( const HdfFile &hdfFile )
|
||||||
{
|
{
|
||||||
HdfGroup gResults = openHdfGroup( hdfFile, "Results" );
|
HdfGroup gResults = openHdfGroup( hdfFile, "Results" );
|
||||||
@ -69,12 +75,64 @@ static HdfGroup get2DFlowAreasGroup( const HdfFile &hdfFile, const std::string l
|
|||||||
return g2DFlowRes;
|
return g2DFlowRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string getDataTimeUnit( HdfDataset &dsTime )
|
||||||
|
{
|
||||||
|
// Initially we expect data to be in hours
|
||||||
|
std::string dataTimeUnit = "Hours";
|
||||||
|
|
||||||
|
// First we look for the Time attribute
|
||||||
|
if ( dsTime.hasAttribute( "Time" ) )
|
||||||
|
{
|
||||||
|
dataTimeUnit = openHdfAttribute( dsTime, "Time" );
|
||||||
|
return dataTimeUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some variants of HEC_RAS have time unit stored in Variables attribute
|
||||||
|
// With read values looking like "Time|Days "
|
||||||
|
if ( dsTime.hasAttribute( "Variables" ) )
|
||||||
|
{
|
||||||
|
dataTimeUnit = openHdfAttribute( dsTime, "Variables" );
|
||||||
|
// Removing the "Time|" prefix
|
||||||
|
dataTimeUnit = MDAL::replace( dataTimeUnit, "Time|", "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataTimeUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void convertTimeDataToHours( std::vector<float> ×, const std::string &originalTimeDataUnit )
|
||||||
|
{
|
||||||
|
if ( originalTimeDataUnit != "Hours" )
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < times.size(); i++ )
|
||||||
|
{
|
||||||
|
if ( originalTimeDataUnit == "Seconds" ) { times[i] /= 3600.0f; }
|
||||||
|
else if ( originalTimeDataUnit == "Minutes" ) { times[i] /= 60.0f; }
|
||||||
|
else if ( originalTimeDataUnit == "Days" ) { times[i] *= 24; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string readReferenceTime( const HdfFile &hdfFile )
|
||||||
|
{
|
||||||
|
std::string refTime;
|
||||||
|
HdfGroup gBaseO = getBaseOutputGroup( hdfFile );
|
||||||
|
HdfGroup gUnsteadTS = openHdfGroup( gBaseO, "Unsteady Time Series" );
|
||||||
|
HdfDataset dsTimeDateStamp = openHdfDataset( gUnsteadTS, "Time Date Stamp" );
|
||||||
|
std::vector<std::string> timeStamps = dsTimeDateStamp.readArrayString();
|
||||||
|
|
||||||
|
if ( timeStamps.size() > 0 )
|
||||||
|
refTime = timeStamps[0];
|
||||||
|
return refTime;
|
||||||
|
}
|
||||||
|
|
||||||
static std::vector<float> readTimes( const HdfFile &hdfFile )
|
static std::vector<float> readTimes( const HdfFile &hdfFile )
|
||||||
{
|
{
|
||||||
HdfGroup gBaseO = getBaseOutputGroup( hdfFile );
|
HdfGroup gBaseO = getBaseOutputGroup( hdfFile );
|
||||||
HdfGroup gUnsteadTS = openHdfGroup( gBaseO, "Unsteady Time Series" );
|
HdfGroup gUnsteadTS = openHdfGroup( gBaseO, "Unsteady Time Series" );
|
||||||
HdfDataset dsTimes = openHdfDataset( gUnsteadTS, "Time" );
|
HdfDataset dsTime = openHdfDataset( gUnsteadTS, "Time" );
|
||||||
std::vector<float> times = dsTimes.readArray();
|
std::string dataTimeUnits = getDataTimeUnit( dsTime );
|
||||||
|
std::vector<float> times = dsTime.readArray();
|
||||||
|
convertTimeDataToHours( times, dataTimeUnits );
|
||||||
return times;
|
return times;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +157,8 @@ void MDAL::DriverHec2D::readFaceOutput( const HdfFile &hdfFile,
|
|||||||
const std::vector<std::string> &flowAreaNames,
|
const std::vector<std::string> &flowAreaNames,
|
||||||
const std::string rawDatasetName,
|
const std::string rawDatasetName,
|
||||||
const std::string datasetName,
|
const std::string datasetName,
|
||||||
const std::vector<float> × )
|
const std::vector<float> ×,
|
||||||
|
const std::string &referenceTime )
|
||||||
{
|
{
|
||||||
double eps = std::numeric_limits<double>::min();
|
double eps = std::numeric_limits<double>::min();
|
||||||
|
|
||||||
@ -111,6 +170,7 @@ void MDAL::DriverHec2D::readFaceOutput( const HdfFile &hdfFile,
|
|||||||
);
|
);
|
||||||
group->setIsOnVertices( false );
|
group->setIsOnVertices( false );
|
||||||
group->setIsScalar( true );
|
group->setIsScalar( true );
|
||||||
|
group->setReferenceTime( referenceTime );
|
||||||
|
|
||||||
std::vector<std::shared_ptr<MDAL::MemoryDataset>> datasets;
|
std::vector<std::shared_ptr<MDAL::MemoryDataset>> datasets;
|
||||||
|
|
||||||
@ -177,17 +237,17 @@ void MDAL::DriverHec2D::readFaceResults( const HdfFile &hdfFile,
|
|||||||
// UNSTEADY
|
// UNSTEADY
|
||||||
HdfGroup flowGroup = get2DFlowAreasGroup( hdfFile, "Unsteady Time Series" );
|
HdfGroup flowGroup = get2DFlowAreasGroup( hdfFile, "Unsteady Time Series" );
|
||||||
std::vector<float> times = readTimes( hdfFile );
|
std::vector<float> times = readTimes( hdfFile );
|
||||||
|
const std::string referenceTime = readReferenceTime( hdfFile );
|
||||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Face Shear Stress", "Face Shear Stress", times );
|
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Face Shear Stress", "Face Shear Stress", times, referenceTime );
|
||||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Face Velocity", "Face Velocity", times );
|
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Face Velocity", "Face Velocity", times, referenceTime );
|
||||||
|
|
||||||
// SUMMARY
|
// SUMMARY
|
||||||
flowGroup = get2DFlowAreasGroup( hdfFile, "Summary Output" );
|
flowGroup = get2DFlowAreasGroup( hdfFile, "Summary Output" );
|
||||||
times.clear();
|
times.clear();
|
||||||
times.push_back( 0.0f );
|
times.push_back( 0.0f );
|
||||||
|
|
||||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Maximum Face Shear Stress", "Face Shear Stress/Maximums", times );
|
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Maximum Face Shear Stress", "Face Shear Stress/Maximums", times, referenceTime );
|
||||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Maximum Face Velocity", "Face Velocity/Maximums", times );
|
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Maximum Face Velocity", "Face Velocity/Maximums", times, referenceTime );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -197,7 +257,8 @@ std::shared_ptr<MDAL::MemoryDataset> MDAL::DriverHec2D::readElemOutput( const Hd
|
|||||||
const std::string rawDatasetName,
|
const std::string rawDatasetName,
|
||||||
const std::string datasetName,
|
const std::string datasetName,
|
||||||
const std::vector<float> ×,
|
const std::vector<float> ×,
|
||||||
std::shared_ptr<MDAL::MemoryDataset> bed_elevation )
|
std::shared_ptr<MDAL::MemoryDataset> bed_elevation,
|
||||||
|
const std::string &referenceTime )
|
||||||
{
|
{
|
||||||
double eps = std::numeric_limits<double>::min();
|
double eps = std::numeric_limits<double>::min();
|
||||||
|
|
||||||
@ -209,6 +270,7 @@ std::shared_ptr<MDAL::MemoryDataset> MDAL::DriverHec2D::readElemOutput( const Hd
|
|||||||
);
|
);
|
||||||
group->setIsOnVertices( false );
|
group->setIsOnVertices( false );
|
||||||
group->setIsScalar( true );
|
group->setIsScalar( true );
|
||||||
|
group->setReferenceTime( referenceTime );
|
||||||
|
|
||||||
std::vector<std::shared_ptr<MDAL::MemoryDataset>> datasets;
|
std::vector<std::shared_ptr<MDAL::MemoryDataset>> datasets;
|
||||||
|
|
||||||
@ -287,6 +349,8 @@ std::shared_ptr<MDAL::MemoryDataset> MDAL::DriverHec2D::readBedElevation(
|
|||||||
const std::vector<std::string> &flowAreaNames )
|
const std::vector<std::string> &flowAreaNames )
|
||||||
{
|
{
|
||||||
std::vector<float> times( 1, 0.0f );
|
std::vector<float> times( 1, 0.0f );
|
||||||
|
std::string referenceTime;
|
||||||
|
|
||||||
return readElemOutput(
|
return readElemOutput(
|
||||||
gGeom2DFlowAreas,
|
gGeom2DFlowAreas,
|
||||||
areaElemStartIndex,
|
areaElemStartIndex,
|
||||||
@ -294,7 +358,8 @@ std::shared_ptr<MDAL::MemoryDataset> MDAL::DriverHec2D::readBedElevation(
|
|||||||
"Cells Minimum Elevation",
|
"Cells Minimum Elevation",
|
||||||
"Bed Elevation",
|
"Bed Elevation",
|
||||||
times,
|
times,
|
||||||
std::shared_ptr<MDAL::MemoryDataset>()
|
std::shared_ptr<MDAL::MemoryDataset>(),
|
||||||
|
referenceTime
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,6 +372,7 @@ void MDAL::DriverHec2D::readElemResults(
|
|||||||
// UNSTEADY
|
// UNSTEADY
|
||||||
HdfGroup flowGroup = get2DFlowAreasGroup( hdfFile, "Unsteady Time Series" );
|
HdfGroup flowGroup = get2DFlowAreasGroup( hdfFile, "Unsteady Time Series" );
|
||||||
std::vector<float> times = readTimes( hdfFile );
|
std::vector<float> times = readTimes( hdfFile );
|
||||||
|
std::string referenceTime = readReferenceTime( hdfFile );
|
||||||
|
|
||||||
readElemOutput(
|
readElemOutput(
|
||||||
flowGroup,
|
flowGroup,
|
||||||
@ -315,7 +381,8 @@ void MDAL::DriverHec2D::readElemResults(
|
|||||||
"Water Surface",
|
"Water Surface",
|
||||||
"Water Surface",
|
"Water Surface",
|
||||||
times,
|
times,
|
||||||
bed_elevation );
|
bed_elevation,
|
||||||
|
referenceTime );
|
||||||
readElemOutput(
|
readElemOutput(
|
||||||
flowGroup,
|
flowGroup,
|
||||||
areaElemStartIndex,
|
areaElemStartIndex,
|
||||||
@ -323,12 +390,14 @@ void MDAL::DriverHec2D::readElemResults(
|
|||||||
"Depth",
|
"Depth",
|
||||||
"Depth",
|
"Depth",
|
||||||
times,
|
times,
|
||||||
bed_elevation );
|
bed_elevation,
|
||||||
|
referenceTime );
|
||||||
|
|
||||||
// SUMMARY
|
// SUMMARY
|
||||||
flowGroup = get2DFlowAreasGroup( hdfFile, "Summary Output" );
|
flowGroup = get2DFlowAreasGroup( hdfFile, "Summary Output" );
|
||||||
times.clear();
|
times.clear();
|
||||||
times.push_back( 0.0f );
|
times.push_back( 0.0f );
|
||||||
|
referenceTime.clear();
|
||||||
|
|
||||||
readElemOutput(
|
readElemOutput(
|
||||||
flowGroup,
|
flowGroup,
|
||||||
@ -337,7 +406,8 @@ void MDAL::DriverHec2D::readElemResults(
|
|||||||
"Maximum Water Surface",
|
"Maximum Water Surface",
|
||||||
"Water Surface/Maximums",
|
"Water Surface/Maximums",
|
||||||
times,
|
times,
|
||||||
bed_elevation
|
bed_elevation,
|
||||||
|
referenceTime
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
external/mdal/frmts/mdal_hec2d.hpp
vendored
14
external/mdal/frmts/mdal_hec2d.hpp
vendored
@ -26,6 +26,14 @@ namespace MDAL
|
|||||||
* There is a small change in the format in HEC-RAS 5.0.5+, where
|
* There is a small change in the format in HEC-RAS 5.0.5+, where
|
||||||
* - Header File Type is different (HEC-RAS Results vs HEC-RAS Geometry)
|
* - Header File Type is different (HEC-RAS Results vs HEC-RAS Geometry)
|
||||||
* - Names or areas are stored in different place (names array vs attributes array)
|
* - Names or areas are stored in different place (names array vs attributes array)
|
||||||
|
*
|
||||||
|
* Time data unit should be present in Time dataset and Time or Variable attribute for given dataset root,
|
||||||
|
* Since MDAL API is reporting times in float hours, the original values need to be corrected
|
||||||
|
* based on value found in the Time attribute.
|
||||||
|
*
|
||||||
|
* All reference times can be found in Time Data Stamp dataset.
|
||||||
|
* First value in the dataset is reported by MDAL as reference time
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
class DriverHec2D: public Driver
|
class DriverHec2D: public Driver
|
||||||
{
|
{
|
||||||
@ -56,7 +64,8 @@ namespace MDAL
|
|||||||
const std::vector<std::string> &flowAreaNames,
|
const std::vector<std::string> &flowAreaNames,
|
||||||
const std::string rawDatasetName,
|
const std::string rawDatasetName,
|
||||||
const std::string datasetName,
|
const std::string datasetName,
|
||||||
const std::vector<float> × );
|
const std::vector<float> ×,
|
||||||
|
const std::string &referenceTime );
|
||||||
|
|
||||||
void readFaceResults( const HdfFile &hdfFile,
|
void readFaceResults( const HdfFile &hdfFile,
|
||||||
const std::vector<size_t> &areaElemStartIndex,
|
const std::vector<size_t> &areaElemStartIndex,
|
||||||
@ -69,7 +78,8 @@ namespace MDAL
|
|||||||
const std::string rawDatasetName,
|
const std::string rawDatasetName,
|
||||||
const std::string datasetName,
|
const std::string datasetName,
|
||||||
const std::vector<float> ×,
|
const std::vector<float> ×,
|
||||||
std::shared_ptr<MDAL::MemoryDataset> bed_elevation );
|
std::shared_ptr<MDAL::MemoryDataset> bed_elevation,
|
||||||
|
const std::string &referenceTime );
|
||||||
|
|
||||||
std::shared_ptr<MDAL::MemoryDataset> readBedElevation(
|
std::shared_ptr<MDAL::MemoryDataset> readBedElevation(
|
||||||
const HdfGroup &gGeom2DFlowAreas,
|
const HdfGroup &gGeom2DFlowAreas,
|
||||||
|
34
external/mdal/frmts/mdal_netcdf.cpp
vendored
34
external/mdal/frmts/mdal_netcdf.cpp
vendored
@ -82,6 +82,19 @@ std::vector<std::string> NetCDFFile::readArrNames() const
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NetCDFFile::hasAttrInt( const std::string &name, const std::string &attr_name ) const
|
||||||
|
{
|
||||||
|
assert( mNcid != 0 );
|
||||||
|
|
||||||
|
int arr_id;
|
||||||
|
if ( nc_inq_varid( mNcid, name.c_str(), &arr_id ) != NC_NOERR ) return false;
|
||||||
|
|
||||||
|
int val;
|
||||||
|
if ( nc_get_att_int( mNcid, arr_id, attr_name.c_str(), &val ) ) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int NetCDFFile::getAttrInt( const std::string &name, const std::string &attr_name ) const
|
int NetCDFFile::getAttrInt( const std::string &name, const std::string &attr_name ) const
|
||||||
{
|
{
|
||||||
assert( mNcid != 0 );
|
assert( mNcid != 0 );
|
||||||
@ -155,6 +168,27 @@ void NetCDFFile::getDimension( const std::string &name, size_t *val, int *ncid_v
|
|||||||
if ( nc_inq_dimlen( mNcid, *ncid_val, val ) != NC_NOERR ) throw MDAL_Status::Err_UnknownFormat;
|
if ( nc_inq_dimlen( mNcid, *ncid_val, val ) != NC_NOERR ) throw MDAL_Status::Err_UnknownFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetCDFFile::getDimensions( const std::string &variableName, std::vector<size_t> &dimensions, std::vector<int> &dimensionIds )
|
||||||
|
{
|
||||||
|
assert( mNcid != 0 );
|
||||||
|
|
||||||
|
int n;
|
||||||
|
int varId;
|
||||||
|
if ( nc_inq_varid( mNcid, variableName.c_str(), &varId ) ) throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
if ( nc_inq_varndims( mNcid, varId, &n ) ) throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
|
||||||
|
dimensionIds.resize( size_t( n ) );
|
||||||
|
dimensions.resize( size_t( n ) );
|
||||||
|
|
||||||
|
if ( nc_inq_vardimid( mNcid, varId, dimensionIds.data() ) ) throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
|
||||||
|
for ( int i = 0; i < n; ++i )
|
||||||
|
{
|
||||||
|
nc_inq_dimlen( mNcid, dimensionIds[size_t( i )], &dimensions[size_t( i )] );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool NetCDFFile::hasDimension( const std::string &name ) const
|
bool NetCDFFile::hasDimension( const std::string &name ) const
|
||||||
{
|
{
|
||||||
int ncid_val;
|
int ncid_val;
|
||||||
|
2
external/mdal/frmts/mdal_netcdf.hpp
vendored
2
external/mdal/frmts/mdal_netcdf.hpp
vendored
@ -26,6 +26,7 @@ class NetCDFFile
|
|||||||
bool hasArr( const std::string &name ) const;
|
bool hasArr( const std::string &name ) const;
|
||||||
std::vector<std::string> readArrNames() const;
|
std::vector<std::string> readArrNames() const;
|
||||||
|
|
||||||
|
bool hasAttrInt( const std::string &name, const std::string &attr_name ) const;
|
||||||
int getAttrInt( const std::string &name, const std::string &attr_name ) const;
|
int getAttrInt( const std::string &name, const std::string &attr_name ) const;
|
||||||
double getAttrDouble( int varid, const std::string &attr_name ) const;
|
double getAttrDouble( int varid, const std::string &attr_name ) const;
|
||||||
/**
|
/**
|
||||||
@ -39,6 +40,7 @@ class NetCDFFile
|
|||||||
double getFillValue( int varid ) const;
|
double getFillValue( int varid ) const;
|
||||||
int getVarId( const std::string &name );
|
int getVarId( const std::string &name );
|
||||||
void getDimension( const std::string &name, size_t *val, int *ncid_val ) const;
|
void getDimension( const std::string &name, size_t *val, int *ncid_val ) const;
|
||||||
|
void getDimensions( const std::string &variableName, std::vector<size_t> &dimensionsId, std::vector<int> &dimensionIds );
|
||||||
bool hasDimension( const std::string &name ) const;
|
bool hasDimension( const std::string &name ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
36
external/mdal/frmts/mdal_selafin.cpp
vendored
36
external/mdal/frmts/mdal_selafin.cpp
vendored
@ -145,35 +145,18 @@ std::string MDAL::SerafinStreamReader::read_string_without_length( size_t len )
|
|||||||
double MDAL::SerafinStreamReader::read_double( )
|
double MDAL::SerafinStreamReader::read_double( )
|
||||||
{
|
{
|
||||||
double ret;
|
double ret;
|
||||||
unsigned char buffer[8];
|
|
||||||
|
|
||||||
if ( mStreamInFloatPrecision )
|
if ( mStreamInFloatPrecision )
|
||||||
{
|
{
|
||||||
float ret_f;
|
float ret_f;
|
||||||
if ( mIn.read( reinterpret_cast< char * >( &buffer ), 4 ) )
|
if ( !readValue( ret_f, mIn, mIsNativeLittleEndian ) )
|
||||||
if ( !mIn )
|
|
||||||
throw MDAL_Status::Err_UnknownFormat;
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
if ( mIsNativeLittleEndian )
|
|
||||||
{
|
|
||||||
std::reverse( reinterpret_cast< char * >( &buffer ), reinterpret_cast< char * >( &buffer ) + 4 );
|
|
||||||
}
|
|
||||||
memcpy( reinterpret_cast< char * >( &ret_f ),
|
|
||||||
reinterpret_cast< char * >( &buffer ),
|
|
||||||
4 );
|
|
||||||
ret = static_cast<double>( ret_f );
|
ret = static_cast<double>( ret_f );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( mIn.read( reinterpret_cast< char * >( &buffer ), 8 ) )
|
if ( !readValue( ret, mIn, mIsNativeLittleEndian ) )
|
||||||
if ( !mIn )
|
|
||||||
throw MDAL_Status::Err_UnknownFormat;
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
if ( mIsNativeLittleEndian )
|
|
||||||
{
|
|
||||||
std::reverse( reinterpret_cast< char * >( &buffer ), reinterpret_cast< char * >( &buffer ) + 8 );
|
|
||||||
}
|
|
||||||
memcpy( reinterpret_cast< char * >( &ret ),
|
|
||||||
reinterpret_cast< char * >( &buffer ),
|
|
||||||
8 );
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -453,6 +436,20 @@ void MDAL::DriverSelafin::addData( const std::vector<std::string> &var_names, co
|
|||||||
var_name = MDAL::replace( var_name, "along y", "" );
|
var_name = MDAL::replace( var_name, "along y", "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( MDAL::contains( var_name, "vitesse u" ) || MDAL::contains( var_name, "suivant x" ) )
|
||||||
|
{
|
||||||
|
is_vector = true;
|
||||||
|
var_name = MDAL::replace( var_name, "vitesse u", "vitesse" );
|
||||||
|
var_name = MDAL::replace( var_name, "suivant x", "" );
|
||||||
|
}
|
||||||
|
else if ( MDAL::contains( var_name, "vitesse v" ) || MDAL::contains( var_name, "suivant y" ) )
|
||||||
|
{
|
||||||
|
is_vector = true;
|
||||||
|
is_x = false;
|
||||||
|
var_name = MDAL::replace( var_name, "vitesse v", "vitesse" );
|
||||||
|
var_name = MDAL::replace( var_name, "suivant y", "" );
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<DatasetGroup> group = mMesh->group( var_name );
|
std::shared_ptr<DatasetGroup> group = mMesh->group( var_name );
|
||||||
if ( !group )
|
if ( !group )
|
||||||
{
|
{
|
||||||
@ -601,6 +598,5 @@ std::unique_ptr<MDAL::Mesh> MDAL::DriverSelafin::load( const std::string &meshFi
|
|||||||
if ( status ) *status = ( error );
|
if ( status ) *status = ( error );
|
||||||
mMesh.reset();
|
mMesh.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::unique_ptr<Mesh>( mMesh.release() );
|
return std::unique_ptr<Mesh>( mMesh.release() );
|
||||||
}
|
}
|
||||||
|
5
external/mdal/frmts/mdal_sww.cpp
vendored
5
external/mdal/frmts/mdal_sww.cpp
vendored
@ -190,6 +190,11 @@ void MDAL::DriverSWW::readDatasetGroups(
|
|||||||
|
|
||||||
for ( const std::string &name : names )
|
for ( const std::string &name : names )
|
||||||
{
|
{
|
||||||
|
// currently we do not support variables like elevation_c, friction_c, stage_c, xmomentum_c, ymomentum_c
|
||||||
|
// which contain values per volume instead of per vertex
|
||||||
|
if ( MDAL::endsWith( name, "_c" ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
// skip already parsed variables
|
// skip already parsed variables
|
||||||
if ( parsedVariableNames.find( name ) == parsedVariableNames.cend() )
|
if ( parsedVariableNames.find( name ) == parsedVariableNames.cend() )
|
||||||
{
|
{
|
||||||
|
132
external/mdal/frmts/mdal_ugrid.cpp
vendored
132
external/mdal/frmts/mdal_ugrid.cpp
vendored
@ -45,8 +45,21 @@ std::string MDAL::DriverUgrid::findMeshName( int dimension, bool optional ) cons
|
|||||||
|
|
||||||
std::string MDAL::DriverUgrid::nodeZVariableName() const
|
std::string MDAL::DriverUgrid::nodeZVariableName() const
|
||||||
{
|
{
|
||||||
// looks like mesh attributes does not have node_z array name
|
const std::vector<std::string> variables = mNcFile.readArrNames();
|
||||||
// reference
|
for ( const std::string &varName : variables )
|
||||||
|
{
|
||||||
|
const std::string stdName = mNcFile.getAttrStr( varName, "standard_name" );
|
||||||
|
const std::string meshName = mNcFile.getAttrStr( varName, "mesh" );
|
||||||
|
const std::string location = mNcFile.getAttrStr( varName, "location" );
|
||||||
|
|
||||||
|
if ( stdName == "altitude" && meshName == mMesh2dName && location == "node" )
|
||||||
|
{
|
||||||
|
return varName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// not found, the file in non UGRID standard conforming,
|
||||||
|
// but lets try the common name
|
||||||
return mMesh2dName + "_node_z";
|
return mMesh2dName + "_node_z";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,33 +74,91 @@ MDAL::CFDimensions MDAL::DriverUgrid::populateDimensions( )
|
|||||||
|
|
||||||
// 2D Mesh
|
// 2D Mesh
|
||||||
|
|
||||||
// node_dimension is usually something like nMesh2D_node
|
//node dimension location is retrieved from the node variable
|
||||||
// number of nodes/vertices in the mesh
|
|
||||||
const std::string mesh2dNode = mNcFile.getAttrStr( mMesh2dName, "node_dimension" );
|
|
||||||
mNcFile.getDimension( mesh2dNode, &count, &ncid );
|
|
||||||
dims.setDimension( CFDimensions::Vertex2D, count, ncid );
|
|
||||||
|
|
||||||
// face_dimension is usually something like nMesh2D_face
|
std::vector<std::string> nodeVariablesName = MDAL::split( mNcFile.getAttrStr( mMesh2dName, "node_coordinates" ), ' ' );
|
||||||
// number of faces in the mesh
|
if ( nodeVariablesName.size() < 2 )
|
||||||
const std::string mesh2dFace = mNcFile.getAttrStr( mMesh2dName, "face_dimension" );
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
mNcFile.getDimension( mesh2dFace, &count, &ncid );
|
|
||||||
dims.setDimension( CFDimensions::Face2D, count, ncid );
|
|
||||||
|
|
||||||
// edge_dimension is usually something like nMesh2D_edge
|
std::vector<size_t> nodeDimension;
|
||||||
// number of edges in the mesh
|
std::vector<int> nodeDimensionId;
|
||||||
|
mNcFile.getDimensions( nodeVariablesName.at( 0 ), nodeDimension, nodeDimensionId );
|
||||||
|
if ( nodeDimension.size() != 1 )
|
||||||
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
|
||||||
|
dims.setDimension( CFDimensions::Vertex2D, nodeDimension.at( 0 ), nodeDimensionId.at( 0 ) );
|
||||||
|
|
||||||
|
|
||||||
|
//face dimension location is retrieved from the face_node_connectivity variable
|
||||||
|
//if face_dimension is defined as attribute, the dimension at this location help to desambiguate vertex per faces and number of faces
|
||||||
|
|
||||||
|
std::string faceConnectivityVariablesName = mNcFile.getAttrStr( mMesh2dName, "face_node_connectivity" );
|
||||||
|
std::string faceDimensionLocation = mNcFile.getAttrStr( mMesh2dName, "face_dimension" );
|
||||||
|
if ( faceConnectivityVariablesName == "" )
|
||||||
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
|
||||||
|
size_t facesCount;
|
||||||
|
size_t maxVerticesPerFace;
|
||||||
|
|
||||||
|
std::vector<size_t> faceDimension;
|
||||||
|
std::vector<int> faceDimensionId;
|
||||||
|
int facesIndexDimensionId;
|
||||||
|
int maxVerticesPerFaceDimensionId;
|
||||||
|
mNcFile.getDimensions( faceConnectivityVariablesName, faceDimension, faceDimensionId );
|
||||||
|
if ( faceDimension.size() != 2 )
|
||||||
|
throw MDAL_Status::Err_UnknownFormat;
|
||||||
|
|
||||||
|
if ( faceDimensionLocation != "" )
|
||||||
|
{
|
||||||
|
mNcFile.getDimension( faceDimensionLocation, &facesCount, &ncid );
|
||||||
|
if ( facesCount == faceDimension.at( 0 ) )
|
||||||
|
{
|
||||||
|
facesIndexDimensionId = faceDimensionId.at( 0 );
|
||||||
|
maxVerticesPerFaceDimensionId = faceDimensionId.at( 1 );
|
||||||
|
maxVerticesPerFace = faceDimension.at( 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
facesIndexDimensionId = faceDimensionId.at( 1 );
|
||||||
|
maxVerticesPerFaceDimensionId = faceDimensionId.at( 0 );
|
||||||
|
maxVerticesPerFace = faceDimension.at( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
facesIndexDimensionId = faceDimensionId.at( 0 );
|
||||||
|
facesCount = faceDimension.at( 0 );
|
||||||
|
maxVerticesPerFaceDimensionId = faceDimensionId.at( 1 );
|
||||||
|
maxVerticesPerFace = faceDimension.at( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
dims.setDimension( CFDimensions::Face2D, facesCount, facesIndexDimensionId );
|
||||||
|
dims.setDimension( CFDimensions::MaxVerticesInFace, maxVerticesPerFace, maxVerticesPerFaceDimensionId );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// number of edges in the mesh, not required for UGRID format
|
||||||
const std::string mesh2dEdge = mNcFile.getAttrStr( mMesh2dName, "edge_dimension" );
|
const std::string mesh2dEdge = mNcFile.getAttrStr( mMesh2dName, "edge_dimension" );
|
||||||
|
if ( mNcFile.hasDimension( mesh2dEdge ) )
|
||||||
|
{
|
||||||
mNcFile.getDimension( mesh2dEdge, &count, &ncid );
|
mNcFile.getDimension( mesh2dEdge, &count, &ncid );
|
||||||
dims.setDimension( CFDimensions::Face2DEdge, count, ncid );
|
dims.setDimension( CFDimensions::Face2DEdge, count, ncid );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dims.setDimension( CFDimensions::Face2DEdge, 0, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
// max_face_nodes_dimension is usually something like max_nMesh2D_face_nodes
|
// Time not required for UGRID format
|
||||||
// maximum number of vertices in faces
|
if ( mNcFile.hasDimension( "time" ) )
|
||||||
const std::string mesh2dMaxNodesInFace = mNcFile.getAttrStr( mMesh2dName, "max_face_nodes_dimension" );
|
{
|
||||||
mNcFile.getDimension( mesh2dMaxNodesInFace, &count, &ncid );
|
|
||||||
dims.setDimension( CFDimensions::MaxVerticesInFace, count, ncid );
|
|
||||||
|
|
||||||
// Time
|
|
||||||
mNcFile.getDimension( "time", &count, &ncid );
|
mNcFile.getDimension( "time", &count, &ncid );
|
||||||
dims.setDimension( CFDimensions::Time, count, ncid );
|
dims.setDimension( CFDimensions::Time, count, ncid );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dims.setDimension( CFDimensions::Time, 0, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
return dims;
|
return dims;
|
||||||
}
|
}
|
||||||
@ -138,7 +209,9 @@ void MDAL::DriverUgrid::populateFaces( MDAL::Faces &faces )
|
|||||||
const std::string mesh2dFaceNodeConnectivity = mNcFile.getAttrStr( mMesh2dName, "face_node_connectivity" );
|
const std::string mesh2dFaceNodeConnectivity = mNcFile.getAttrStr( mMesh2dName, "face_node_connectivity" );
|
||||||
|
|
||||||
size_t verticesInFace = mDimensions.size( CFDimensions::MaxVerticesInFace );
|
size_t verticesInFace = mDimensions.size( CFDimensions::MaxVerticesInFace );
|
||||||
int fill_val = mNcFile.getAttrInt( mesh2dFaceNodeConnectivity, "_FillValue" );
|
int fill_val = -1;
|
||||||
|
if ( mNcFile.hasAttrInt( mesh2dFaceNodeConnectivity, "_FillValue" ) )
|
||||||
|
fill_val = mNcFile.getAttrInt( mesh2dFaceNodeConnectivity, "_FillValue" );
|
||||||
int start_index = mNcFile.getAttrInt( mesh2dFaceNodeConnectivity, "start_index" );
|
int start_index = mNcFile.getAttrInt( mesh2dFaceNodeConnectivity, "start_index" );
|
||||||
std::vector<int> face_nodes_conn = mNcFile.readIntArr( mesh2dFaceNodeConnectivity, faceCount * verticesInFace );
|
std::vector<int> face_nodes_conn = mNcFile.readIntArr( mesh2dFaceNodeConnectivity, faceCount * verticesInFace );
|
||||||
|
|
||||||
@ -179,10 +252,15 @@ std::string MDAL::DriverUgrid::getCoordinateSystemVariableName()
|
|||||||
std::string coordinate_system_variable;
|
std::string coordinate_system_variable;
|
||||||
|
|
||||||
// first try to get the coordinate system variable from grid definition
|
// first try to get the coordinate system variable from grid definition
|
||||||
if ( mNcFile.hasArr( nodeZVariableName() ) )
|
std::vector<std::string> nodeVariablesName = MDAL::split( mNcFile.getAttrStr( mMesh2dName, "node_coordinates" ), ' ' );
|
||||||
|
if ( nodeVariablesName.size() > 1 )
|
||||||
{
|
{
|
||||||
coordinate_system_variable = mNcFile.getAttrStr( nodeZVariableName(), "grid_mapping" );
|
if ( mNcFile.hasArr( nodeVariablesName[0] ) )
|
||||||
|
{
|
||||||
|
coordinate_system_variable = mNcFile.getAttrStr( nodeVariablesName[0], "grid_mapping" );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// if automatic discovery fails, try to check some hardcoded common variables that store projection
|
// if automatic discovery fails, try to check some hardcoded common variables that store projection
|
||||||
if ( coordinate_system_variable.empty() )
|
if ( coordinate_system_variable.empty() )
|
||||||
@ -281,16 +359,18 @@ void MDAL::DriverUgrid::parseNetCDFVariableMetadata( int varid, const std::strin
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( MDAL::contains( long_name, ", x-component" ) )
|
if ( MDAL::contains( long_name, ", x-component" ) || MDAL::contains( long_name, "u component of " ) )
|
||||||
{
|
{
|
||||||
*is_vector = true;
|
*is_vector = true;
|
||||||
name = MDAL::replace( long_name, ", x-component", "" );
|
name = MDAL::replace( long_name, ", x-component", "" );
|
||||||
|
name = MDAL::replace( name, "u component of ", "" );
|
||||||
}
|
}
|
||||||
else if ( MDAL::contains( long_name, ", y-component" ) )
|
else if ( MDAL::contains( long_name, ", y-component" ) || MDAL::contains( long_name, "v component of " ) )
|
||||||
{
|
{
|
||||||
*is_vector = true;
|
*is_vector = true;
|
||||||
*is_x = false;
|
*is_x = false;
|
||||||
name = MDAL::replace( long_name, ", y-component", "" );
|
name = MDAL::replace( long_name, ", y-component", "" );
|
||||||
|
name = MDAL::replace( name, "v component of ", "" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
17
external/mdal/frmts/mdal_xmdf.cpp
vendored
17
external/mdal/frmts/mdal_xmdf.cpp
vendored
@ -247,7 +247,8 @@ std::shared_ptr<MDAL::DatasetGroup> MDAL::DriverXmdf::readXmdfGroupAsDatasetGrou
|
|||||||
bool isVector = dimValues.size() == 3;
|
bool isVector = dimValues.size() == 3;
|
||||||
|
|
||||||
std::vector<double> times = dsTimes.readArrayDouble();
|
std::vector<double> times = dsTimes.readArrayDouble();
|
||||||
|
std::string timeUnit = rootGroup.attribute( "TimeUnits" ).readString();
|
||||||
|
convertTimeDataToHours( times, timeUnit );
|
||||||
// all fine, set group and return
|
// all fine, set group and return
|
||||||
group = std::make_shared<MDAL::DatasetGroup>(
|
group = std::make_shared<MDAL::DatasetGroup>(
|
||||||
name(),
|
name(),
|
||||||
@ -257,6 +258,7 @@ std::shared_ptr<MDAL::DatasetGroup> MDAL::DriverXmdf::readXmdfGroupAsDatasetGrou
|
|||||||
);
|
);
|
||||||
group->setIsScalar( !isVector );
|
group->setIsScalar( !isVector );
|
||||||
group->setIsOnVertices( true );
|
group->setIsOnVertices( true );
|
||||||
|
group->setMetadata( "TIMEUNITS", timeUnit );
|
||||||
|
|
||||||
// lazy loading of min and max of the dataset group
|
// lazy loading of min and max of the dataset group
|
||||||
std::vector<float> mins = dsMins.readArray();
|
std::vector<float> mins = dsMins.readArray();
|
||||||
@ -279,3 +281,16 @@ std::shared_ptr<MDAL::DatasetGroup> MDAL::DriverXmdf::readXmdfGroupAsDatasetGrou
|
|||||||
|
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MDAL::DriverXmdf::convertTimeDataToHours( std::vector<double> ×, const std::string &originalTimeDataUnit )
|
||||||
|
{
|
||||||
|
if ( originalTimeDataUnit != "Hours" )
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < times.size(); i++ )
|
||||||
|
{
|
||||||
|
if ( originalTimeDataUnit == "Seconds" ) { times[i] /= 3600.0; }
|
||||||
|
else if ( originalTimeDataUnit == "Minutes" ) { times[i] /= 60.0; }
|
||||||
|
else if ( originalTimeDataUnit == "Days" ) { times[i] *= 24; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
external/mdal/frmts/mdal_xmdf.hpp
vendored
2
external/mdal/frmts/mdal_xmdf.hpp
vendored
@ -100,6 +100,8 @@ namespace MDAL
|
|||||||
const std::string &nameSuffix,
|
const std::string &nameSuffix,
|
||||||
size_t vertexCount,
|
size_t vertexCount,
|
||||||
size_t faceCount );
|
size_t faceCount );
|
||||||
|
|
||||||
|
void convertTimeDataToHours( std::vector<double> ×, const std::string &originalTimeDataUnit );
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace MDAL
|
} // namespace MDAL
|
||||||
|
58
external/mdal/mdal.cpp
vendored
58
external/mdal/mdal.cpp
vendored
@ -22,7 +22,7 @@ static MDAL_Status sLastStatus;
|
|||||||
|
|
||||||
const char *MDAL_Version()
|
const char *MDAL_Version()
|
||||||
{
|
{
|
||||||
return "0.3.3";
|
return "0.4.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
MDAL_Status MDAL_LastStatus()
|
MDAL_Status MDAL_LastStatus()
|
||||||
@ -92,6 +92,18 @@ bool MDAL_DR_writeDatasetsCapability( DriverH driver )
|
|||||||
return d->hasCapability( MDAL::Capability::WriteDatasets );
|
return d->hasCapability( MDAL::Capability::WriteDatasets );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MDAL_DR_SaveMeshCapability( DriverH driver )
|
||||||
|
{
|
||||||
|
if ( !driver )
|
||||||
|
{
|
||||||
|
sLastStatus = MDAL_Status::Err_MissingDriver;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MDAL::Driver *d = static_cast< MDAL::Driver * >( driver );
|
||||||
|
return d->hasCapability( MDAL::Capability::SaveMesh );
|
||||||
|
}
|
||||||
|
|
||||||
const char *MDAL_DR_longName( DriverH driver )
|
const char *MDAL_DR_longName( DriverH driver )
|
||||||
{
|
{
|
||||||
if ( !driver )
|
if ( !driver )
|
||||||
@ -143,6 +155,39 @@ MeshH MDAL_LoadMesh( const char *meshFile )
|
|||||||
return static_cast< MeshH >( MDAL::DriverManager::instance().load( filename, &sLastStatus ).release() );
|
return static_cast< MeshH >( MDAL::DriverManager::instance().load( filename, &sLastStatus ).release() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MDAL_SaveMesh( MeshH mesh, const char *meshFile, const char *driver )
|
||||||
|
{
|
||||||
|
if ( !meshFile )
|
||||||
|
{
|
||||||
|
sLastStatus = MDAL_Status::Err_FileNotFound;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string driverName( driver );
|
||||||
|
auto d = MDAL::DriverManager::instance().driver( driver );
|
||||||
|
|
||||||
|
if ( !d )
|
||||||
|
{
|
||||||
|
sLastStatus = MDAL_Status::Err_MissingDriver;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !d->hasCapability( MDAL::Capability::SaveMesh ) )
|
||||||
|
{
|
||||||
|
sLastStatus = MDAL_Status::Err_MissingDriverCapability;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( d->faceVerticesMaximumCount() < MDAL_M_faceVerticesMaximumCount( mesh ) )
|
||||||
|
{
|
||||||
|
sLastStatus = MDAL_Status::Err_IncompatibleMesh;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string filename( meshFile );
|
||||||
|
MDAL::DriverManager::instance().save( static_cast< MDAL::Mesh * >( mesh ), filename, driverName, &sLastStatus );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MDAL_CloseMesh( MeshH mesh )
|
void MDAL_CloseMesh( MeshH mesh )
|
||||||
{
|
{
|
||||||
@ -686,6 +731,16 @@ void MDAL_G_closeEditMode( DatasetGroupH group )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *MDAL_G_referenceTime( DatasetGroupH group )
|
||||||
|
{
|
||||||
|
if ( !group )
|
||||||
|
{
|
||||||
|
sLastStatus = MDAL_Status::Err_IncompatibleDataset;
|
||||||
|
return EMPTY_STR;
|
||||||
|
}
|
||||||
|
MDAL::DatasetGroup *g = static_cast< MDAL::DatasetGroup * >( group );
|
||||||
|
return _return_str( g->referenceTime() );
|
||||||
|
}
|
||||||
|
|
||||||
void MDAL_G_setMetadata( DatasetGroupH group, const char *key, const char *val )
|
void MDAL_G_setMetadata( DatasetGroupH group, const char *key, const char *val )
|
||||||
{
|
{
|
||||||
@ -867,3 +922,4 @@ void MDAL_D_minimumMaximum( DatasetH dataset, double *min, double *max )
|
|||||||
*min = stats.minimum;
|
*min = stats.minimum;
|
||||||
*max = stats.maximum;
|
*max = stats.maximum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
external/mdal/mdal_data_model.cpp
vendored
10
external/mdal/mdal_data_model.cpp
vendored
@ -155,6 +155,16 @@ void MDAL::DatasetGroup::setStatistics( const Statistics &statistics )
|
|||||||
mStatistics = statistics;
|
mStatistics = statistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string MDAL::DatasetGroup::referenceTime() const
|
||||||
|
{
|
||||||
|
return mReferenceTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MDAL::DatasetGroup::setReferenceTime( const std::string &referenceTime )
|
||||||
|
{
|
||||||
|
mReferenceTime = referenceTime;
|
||||||
|
}
|
||||||
|
|
||||||
MDAL::Mesh *MDAL::DatasetGroup::mesh() const
|
MDAL::Mesh *MDAL::DatasetGroup::mesh() const
|
||||||
{
|
{
|
||||||
return mParent;
|
return mParent;
|
||||||
|
4
external/mdal/mdal_data_model.hpp
vendored
4
external/mdal/mdal_data_model.hpp
vendored
@ -109,6 +109,9 @@ namespace MDAL
|
|||||||
Statistics statistics() const;
|
Statistics statistics() const;
|
||||||
void setStatistics( const Statistics &statistics );
|
void setStatistics( const Statistics &statistics );
|
||||||
|
|
||||||
|
std::string referenceTime() const;
|
||||||
|
void setReferenceTime( const std::string &referenceTime );
|
||||||
|
|
||||||
Mesh *mesh() const;
|
Mesh *mesh() const;
|
||||||
|
|
||||||
bool isInEditMode() const;
|
bool isInEditMode() const;
|
||||||
@ -124,6 +127,7 @@ namespace MDAL
|
|||||||
bool mIsOnVertices = true;
|
bool mIsOnVertices = true;
|
||||||
std::string mUri; // file/uri from where it came
|
std::string mUri; // file/uri from where it came
|
||||||
Statistics mStatistics;
|
Statistics mStatistics;
|
||||||
|
std::string mReferenceTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<std::shared_ptr<DatasetGroup>> DatasetGroups;
|
typedef std::vector<std::shared_ptr<DatasetGroup>> DatasetGroups;
|
||||||
|
12
external/mdal/mdal_driver_manager.cpp
vendored
12
external/mdal/mdal_driver_manager.cpp
vendored
@ -9,6 +9,7 @@
|
|||||||
#include "frmts/mdal_ascii_dat.hpp"
|
#include "frmts/mdal_ascii_dat.hpp"
|
||||||
#include "frmts/mdal_binary_dat.hpp"
|
#include "frmts/mdal_binary_dat.hpp"
|
||||||
#include "frmts/mdal_selafin.hpp"
|
#include "frmts/mdal_selafin.hpp"
|
||||||
|
#include "frmts/mdal_esri_tin.hpp"
|
||||||
#include "mdal_utils.hpp"
|
#include "mdal_utils.hpp"
|
||||||
|
|
||||||
#ifdef HAVE_HDF5
|
#ifdef HAVE_HDF5
|
||||||
@ -92,6 +93,15 @@ void MDAL::DriverManager::loadDatasets( Mesh *mesh, const std::string &datasetFi
|
|||||||
*status = MDAL_Status::Err_UnknownFormat;
|
*status = MDAL_Status::Err_UnknownFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MDAL::DriverManager::save( MDAL::Mesh *mesh, const std::string &uri, const std::string &driverName, MDAL_Status *status ) const
|
||||||
|
{
|
||||||
|
auto selectedDriver = driver( driverName );
|
||||||
|
|
||||||
|
std::unique_ptr<Driver> drv( selectedDriver->create() );
|
||||||
|
|
||||||
|
drv->save( uri, mesh, status );
|
||||||
|
}
|
||||||
|
|
||||||
size_t MDAL::DriverManager::driversCount() const
|
size_t MDAL::DriverManager::driversCount() const
|
||||||
{
|
{
|
||||||
return mDrivers.size();
|
return mDrivers.size();
|
||||||
@ -124,6 +134,7 @@ MDAL::DriverManager::DriverManager()
|
|||||||
// MESH DRIVERS
|
// MESH DRIVERS
|
||||||
mDrivers.push_back( std::make_shared<MDAL::Driver2dm>() );
|
mDrivers.push_back( std::make_shared<MDAL::Driver2dm>() );
|
||||||
mDrivers.push_back( std::make_shared<MDAL::DriverSelafin>() );
|
mDrivers.push_back( std::make_shared<MDAL::DriverSelafin>() );
|
||||||
|
mDrivers.push_back( std::make_shared<MDAL::DriverEsriTin>() );
|
||||||
|
|
||||||
#ifdef HAVE_HDF5
|
#ifdef HAVE_HDF5
|
||||||
mDrivers.push_back( std::make_shared<MDAL::DriverFlo2D>() );
|
mDrivers.push_back( std::make_shared<MDAL::DriverFlo2D>() );
|
||||||
@ -155,3 +166,4 @@ MDAL::DriverManager::DriverManager()
|
|||||||
mDrivers.push_back( std::make_shared<MDAL::DriverXdmf>() );
|
mDrivers.push_back( std::make_shared<MDAL::DriverXdmf>() );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
external/mdal/mdal_driver_manager.hpp
vendored
2
external/mdal/mdal_driver_manager.hpp
vendored
@ -32,6 +32,8 @@ namespace MDAL
|
|||||||
std::unique_ptr< Mesh > load( const std::string &meshFile, MDAL_Status *status ) const;
|
std::unique_ptr< Mesh > load( const std::string &meshFile, MDAL_Status *status ) const;
|
||||||
void loadDatasets( Mesh *mesh, const std::string &datasetFile, MDAL_Status *status ) const;
|
void loadDatasets( Mesh *mesh, const std::string &datasetFile, MDAL_Status *status ) const;
|
||||||
|
|
||||||
|
void save( Mesh *mesh, const std::string &uri, const std::string &driver, MDAL_Status *status ) const;
|
||||||
|
|
||||||
size_t driversCount() const;
|
size_t driversCount() const;
|
||||||
std::shared_ptr<MDAL::Driver> driver( const std::string &driverName ) const;
|
std::shared_ptr<MDAL::Driver> driver( const std::string &driverName ) const;
|
||||||
std::shared_ptr<MDAL::Driver> driver( size_t index ) const;
|
std::shared_ptr<MDAL::Driver> driver( size_t index ) const;
|
||||||
|
40
external/mdal/mdal_utils.cpp
vendored
40
external/mdal/mdal_utils.cpp
vendored
@ -586,3 +586,43 @@ bool MDAL::isNativeLittleEndian()
|
|||||||
int n = 1;
|
int n = 1;
|
||||||
return ( *( char * )&n == 1 );
|
return ( *( char * )&n == 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string MDAL::coordinateToString( double coordinate, int precision )
|
||||||
|
{
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss.setf( std::ios::fixed );
|
||||||
|
if ( fabs( coordinate ) > 180 )
|
||||||
|
oss.precision( precision ); //seems to not be a geographic coordinate, so 'precision' digits after the digital point
|
||||||
|
else
|
||||||
|
oss.precision( 6 + precision ); //could be a geographic coordinate, so 'precision'+6 digits after the digital point
|
||||||
|
|
||||||
|
oss << coordinate;
|
||||||
|
|
||||||
|
std::string returnString = oss.str();
|
||||||
|
returnString.back();
|
||||||
|
|
||||||
|
//remove unnecessary '0' or '.'
|
||||||
|
if ( returnString.size() > 0 )
|
||||||
|
{
|
||||||
|
while ( '0' == returnString.back() )
|
||||||
|
{
|
||||||
|
returnString.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( '.' == returnString.back() )
|
||||||
|
returnString.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnString;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MDAL::doubleToString( double value, int precision )
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss.precision( precision );
|
||||||
|
oss << value;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
29
external/mdal/mdal_utils.hpp
vendored
29
external/mdal/mdal_utils.hpp
vendored
@ -14,6 +14,9 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <sstream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "mdal_data_model.hpp"
|
#include "mdal_data_model.hpp"
|
||||||
#include "mdal_memory_data_model.hpp"
|
#include "mdal_memory_data_model.hpp"
|
||||||
@ -66,6 +69,15 @@ namespace MDAL
|
|||||||
double toDouble( const std::string &str );
|
double toDouble( const std::string &str );
|
||||||
bool toBool( const std::string &str );
|
bool toBool( const std::string &str );
|
||||||
|
|
||||||
|
//! Returns the string with a adapted format to coordinate
|
||||||
|
//! precision is the number of digits after the digital point if fabs(value)>180 (seems to not be a geographic coordinate)
|
||||||
|
//! precision+6 is the number of digits after the digital point if fabs(value)<=180 (could be a geographic coordinate)
|
||||||
|
std::string coordinateToString( double coordinate, int precision = 2 );
|
||||||
|
|
||||||
|
//! Returns a string with scientific format
|
||||||
|
//! precision is the number of signifiant digits
|
||||||
|
std::string doubleToString( double value, int precision = 6 );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits by deliminer and skips empty parts.
|
* Splits by deliminer and skips empty parts.
|
||||||
* Faster than version with std::string
|
* Faster than version with std::string
|
||||||
@ -112,10 +124,25 @@ namespace MDAL
|
|||||||
// mesh & datasets
|
// mesh & datasets
|
||||||
//! Adds bed elevatiom dataset group to mesh
|
//! Adds bed elevatiom dataset group to mesh
|
||||||
void addBedElevationDatasetGroup( MDAL::Mesh *mesh, const Vertices &vertices );
|
void addBedElevationDatasetGroup( MDAL::Mesh *mesh, const Vertices &vertices );
|
||||||
//! Adds face scalar dataset group to mesh
|
//! Adds altitude dataset group to mesh
|
||||||
void addFaceScalarDatasetGroup( MDAL::Mesh *mesh, const std::vector<double> &values, const std::string &name );
|
void addFaceScalarDatasetGroup( MDAL::Mesh *mesh, const std::vector<double> &values, const std::string &name );
|
||||||
//! Loop through all faces and activate those which has all 4 values on vertices valid
|
//! Loop through all faces and activate those which has all 4 values on vertices valid
|
||||||
void activateFaces( MDAL::MemoryMesh *mesh, std::shared_ptr<MemoryDataset> dataset );
|
void activateFaces( MDAL::MemoryMesh *mesh, std::shared_ptr<MemoryDataset> dataset );
|
||||||
|
|
||||||
|
//! function used to read all of type of value. Option to change the endianness is provided
|
||||||
|
template<typename T>
|
||||||
|
bool readValue( T &value, std::ifstream &in, bool changeEndianness = false )
|
||||||
|
{
|
||||||
|
char *const p = reinterpret_cast<char *>( &value );
|
||||||
|
|
||||||
|
if ( !in.read( p, sizeof( T ) ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( changeEndianness )
|
||||||
|
std::reverse( p, p + sizeof( T ) );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace MDAL
|
} // namespace MDAL
|
||||||
#endif //MDAL_UTILS_HPP
|
#endif //MDAL_UTILS_HPP
|
||||||
|
@ -44,6 +44,7 @@ IF (WITH_INTERNAL_MDAL)
|
|||||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_ascii_dat.cpp
|
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_ascii_dat.cpp
|
||||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_binary_dat.cpp
|
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_binary_dat.cpp
|
||||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_selafin.cpp
|
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_selafin.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_esri_tin.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(MDAL_LIB_HDRS
|
SET(MDAL_LIB_HDRS
|
||||||
@ -57,6 +58,7 @@ IF (WITH_INTERNAL_MDAL)
|
|||||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_ascii_dat.hpp
|
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_ascii_dat.hpp
|
||||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_binary_dat.hpp
|
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_binary_dat.hpp
|
||||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_selafin.hpp
|
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_selafin.hpp
|
||||||
|
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_esri_tin.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
IF(HDF5_FOUND)
|
IF(HDF5_FOUND)
|
||||||
|
@ -227,7 +227,7 @@ void TestQgsMeshLayer::test_read_vertex_scalar_dataset()
|
|||||||
QgsMeshDatasetIndex ds( 1, i );
|
QgsMeshDatasetIndex ds( 1, i );
|
||||||
|
|
||||||
const QgsMeshDatasetGroupMetadata meta = dp->datasetGroupMetadata( ds );
|
const QgsMeshDatasetGroupMetadata meta = dp->datasetGroupMetadata( ds );
|
||||||
if ( meta.extraOptions().count() == 2 )
|
if ( dp->name() == QStringLiteral( "mesh_memory" ) )
|
||||||
{
|
{
|
||||||
QCOMPARE( meta.extraOptions()["description"], QString( "Vertex Scalar Dataset" ) );
|
QCOMPARE( meta.extraOptions()["description"], QString( "Vertex Scalar Dataset" ) );
|
||||||
QCOMPARE( meta.extraOptions()["meta2"], QString( "best dataset" ) );
|
QCOMPARE( meta.extraOptions()["meta2"], QString( "best dataset" ) );
|
||||||
@ -270,7 +270,7 @@ void TestQgsMeshLayer::test_read_vertex_vector_dataset()
|
|||||||
QgsMeshDatasetIndex ds( 2, i );
|
QgsMeshDatasetIndex ds( 2, i );
|
||||||
|
|
||||||
const QgsMeshDatasetGroupMetadata meta = dp->datasetGroupMetadata( ds );
|
const QgsMeshDatasetGroupMetadata meta = dp->datasetGroupMetadata( ds );
|
||||||
if ( meta.extraOptions().count() == 2 )
|
if ( dp->name() == QStringLiteral( "mesh_memory" ) )
|
||||||
QCOMPARE( meta.extraOptions()["description"], QString( "Vertex Vector Dataset" ) );
|
QCOMPARE( meta.extraOptions()["description"], QString( "Vertex Vector Dataset" ) );
|
||||||
QCOMPARE( meta.name(), QString( "VertexVectorDataset" ) );
|
QCOMPARE( meta.name(), QString( "VertexVectorDataset" ) );
|
||||||
QVERIFY( !meta.isScalar() );
|
QVERIFY( !meta.isScalar() );
|
||||||
@ -310,7 +310,7 @@ void TestQgsMeshLayer::test_read_face_scalar_dataset()
|
|||||||
QgsMeshDatasetIndex ds( 3, i );
|
QgsMeshDatasetIndex ds( 3, i );
|
||||||
|
|
||||||
const QgsMeshDatasetGroupMetadata meta = dp->datasetGroupMetadata( ds );
|
const QgsMeshDatasetGroupMetadata meta = dp->datasetGroupMetadata( ds );
|
||||||
if ( meta.extraOptions().count() == 2 )
|
if ( dp->name() == QStringLiteral( "mesh_memory" ) )
|
||||||
QCOMPARE( meta.extraOptions()["description"], QString( "Face Scalar Dataset" ) );
|
QCOMPARE( meta.extraOptions()["description"], QString( "Face Scalar Dataset" ) );
|
||||||
QCOMPARE( meta.name(), QString( "FaceScalarDataset" ) );
|
QCOMPARE( meta.name(), QString( "FaceScalarDataset" ) );
|
||||||
QVERIFY( meta.isScalar() );
|
QVERIFY( meta.isScalar() );
|
||||||
@ -348,7 +348,7 @@ void TestQgsMeshLayer::test_read_face_vector_dataset()
|
|||||||
QgsMeshDatasetIndex ds( 4, i );
|
QgsMeshDatasetIndex ds( 4, i );
|
||||||
|
|
||||||
const QgsMeshDatasetGroupMetadata meta = dp->datasetGroupMetadata( ds );
|
const QgsMeshDatasetGroupMetadata meta = dp->datasetGroupMetadata( ds );
|
||||||
if ( meta.extraOptions().count() == 2 )
|
if ( dp->name() == QStringLiteral( "mesh_memory" ) )
|
||||||
QCOMPARE( meta.extraOptions()["description"], QString( "Face Vector Dataset" ) );
|
QCOMPARE( meta.extraOptions()["description"], QString( "Face Vector Dataset" ) );
|
||||||
QCOMPARE( meta.name(), QString( "FaceVectorDataset" ) );
|
QCOMPARE( meta.name(), QString( "FaceVectorDataset" ) );
|
||||||
QVERIFY( !meta.isScalar() );
|
QVERIFY( !meta.isScalar() );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user