mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Update to MDAL 0.1.2
This commit is contained in:
parent
64b81bd976
commit
8b542c8aa4
46
external/mdal/api/mdal.h
vendored
46
external/mdal/api/mdal.h
vendored
@ -68,6 +68,7 @@ typedef void *MeshVertexIteratorH;
|
||||
typedef void *MeshFaceIteratorH;
|
||||
typedef void *DatasetGroupH;
|
||||
typedef void *DatasetH;
|
||||
typedef void *DriverH;
|
||||
|
||||
//! Returns MDAL version
|
||||
MDAL_EXPORT const char *MDAL_Version();
|
||||
@ -75,6 +76,50 @@ MDAL_EXPORT const char *MDAL_Version();
|
||||
//! Returns last status message
|
||||
MDAL_EXPORT MDAL_Status MDAL_LastStatus();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
/// DRIVERS
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Returns count of registed MDAL drivers
|
||||
MDAL_EXPORT int MDAL_driverCount();
|
||||
|
||||
/**
|
||||
* Returns driver handle by index
|
||||
* Do not free the returned pointer
|
||||
*/
|
||||
MDAL_EXPORT DriverH MDAL_driverFromIndex( int index );
|
||||
|
||||
/**
|
||||
* Returns driver handle by name
|
||||
* Do not free the returned pointer
|
||||
*/
|
||||
MDAL_EXPORT DriverH MDAL_driverFromName( const char *name );
|
||||
|
||||
/**
|
||||
* Returns whether driver can be used to mesh
|
||||
* if false, driver can be only used to load datasets to existing mesh
|
||||
*/
|
||||
MDAL_EXPORT bool MDAL_DR_meshLoadCapability( DriverH driver );
|
||||
|
||||
/**
|
||||
* Returns name of MDAL driver
|
||||
* not thread-safe and valid only till next call
|
||||
*/
|
||||
MDAL_EXPORT const char *MDAL_DR_name( DriverH driver );
|
||||
|
||||
/**
|
||||
* Returns long name of MDAL driver
|
||||
* not thread-safe and valid only till next call
|
||||
*/
|
||||
MDAL_EXPORT const char *MDAL_DR_longName( DriverH driver );
|
||||
|
||||
/**
|
||||
* Returns file filters that MDAL driver recognizes
|
||||
* Filters are separated by ;;, e.g. *.abc;;*.def
|
||||
* not thread-safe and valid only till next call
|
||||
*/
|
||||
MDAL_EXPORT const char *MDAL_DR_filters( DriverH driver );
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
/// MESH
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -82,6 +127,7 @@ MDAL_EXPORT MDAL_Status MDAL_LastStatus();
|
||||
/**
|
||||
* Loads mesh file. On error see MDAL_LastStatus for error type
|
||||
* This may effectively load whole mesh in-memory for some providers
|
||||
* Caller must free memory with MDAL_CloseMesh() afterwards
|
||||
*/
|
||||
MDAL_EXPORT MeshH MDAL_LoadMesh( const char *meshFile );
|
||||
//! Closes mesh, frees the memory
|
||||
|
30
external/mdal/frmts/mdal_2dm.cpp
vendored
30
external/mdal/frmts/mdal_2dm.cpp
vendored
@ -57,13 +57,37 @@ size_t MDAL::Mesh2dm::vertexIndex( size_t vertexID ) const
|
||||
}
|
||||
|
||||
|
||||
MDAL::Loader2dm::Loader2dm( const std::string &meshFile ):
|
||||
mMeshFile( meshFile )
|
||||
MDAL::Driver2dm::Driver2dm():
|
||||
Driver( "2DM",
|
||||
"2DM Mesh File",
|
||||
"*.2dm",
|
||||
DriverType::CanReadMeshAndDatasets
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<MDAL::Mesh> MDAL::Loader2dm::load( MDAL_Status *status )
|
||||
MDAL::Driver2dm *MDAL::Driver2dm::create()
|
||||
{
|
||||
return new Driver2dm();
|
||||
}
|
||||
|
||||
MDAL::Driver2dm::~Driver2dm() = default;
|
||||
|
||||
bool MDAL::Driver2dm::canRead( const std::string &uri )
|
||||
{
|
||||
std::ifstream in( uri, std::ifstream::in );
|
||||
std::string line;
|
||||
if ( !std::getline( in, line ) || !startsWith( line, "MESH2D" ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<MDAL::Mesh> MDAL::Driver2dm::load( const std::string &meshFile, MDAL_Status *status )
|
||||
{
|
||||
mMeshFile = meshFile;
|
||||
|
||||
if ( status ) *status = MDAL_Status::None;
|
||||
|
||||
std::ifstream in( mMeshFile, std::ifstream::in );
|
||||
|
11
external/mdal/frmts/mdal_2dm.hpp
vendored
11
external/mdal/frmts/mdal_2dm.hpp
vendored
@ -12,6 +12,7 @@
|
||||
#include "mdal_data_model.hpp"
|
||||
#include "mdal_memory_data_model.hpp"
|
||||
#include "mdal.h"
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
@ -41,11 +42,15 @@ namespace MDAL
|
||||
std::map<size_t, size_t> mVertexIDtoIndex;
|
||||
};
|
||||
|
||||
class Loader2dm
|
||||
class Driver2dm: public Driver
|
||||
{
|
||||
public:
|
||||
Loader2dm( const std::string &meshFile );
|
||||
std::unique_ptr< Mesh > load( MDAL_Status *status );
|
||||
Driver2dm();
|
||||
~Driver2dm() override;
|
||||
Driver2dm *create() override;
|
||||
|
||||
bool canRead( const std::string &uri ) override;
|
||||
std::unique_ptr< Mesh > load( const std::string &meshFile, MDAL_Status *status ) override;
|
||||
|
||||
private:
|
||||
std::string mMeshFile;
|
||||
|
32
external/mdal/frmts/mdal_3di.cpp
vendored
32
external/mdal/frmts/mdal_3di.cpp
vendored
@ -5,35 +5,43 @@
|
||||
|
||||
#include "mdal_3di.hpp"
|
||||
|
||||
MDAL::Loader3Di::Loader3Di( const std::string &fileName )
|
||||
: LoaderCF( fileName )
|
||||
MDAL::Driver3Di::Driver3Di()
|
||||
: DriverCF(
|
||||
"3Di",
|
||||
"3Di Results",
|
||||
"results_3di.nc" )
|
||||
{
|
||||
}
|
||||
|
||||
MDAL::CFDimensions MDAL::Loader3Di::populateDimensions()
|
||||
MDAL::Driver3Di *MDAL::Driver3Di::create()
|
||||
{
|
||||
return new Driver3Di();
|
||||
}
|
||||
|
||||
MDAL::CFDimensions MDAL::Driver3Di::populateDimensions( const NetCDFFile &ncFile )
|
||||
{
|
||||
CFDimensions dims;
|
||||
size_t count;
|
||||
int ncid;
|
||||
|
||||
// 2D Mesh
|
||||
mNcFile.getDimension( "nMesh2D_nodes", &count, &ncid );
|
||||
ncFile.getDimension( "nMesh2D_nodes", &count, &ncid );
|
||||
dims.setDimension( CFDimensions::Face2D, count, ncid );
|
||||
|
||||
mNcFile.getDimension( "nCorner_Nodes", &count, &ncid );
|
||||
ncFile.getDimension( "nCorner_Nodes", &count, &ncid );
|
||||
dims.setDimension( CFDimensions::MaxVerticesInFace, count, ncid );
|
||||
|
||||
// Vertices count is populated later in populateFacesAndVertices
|
||||
// it is not known from the array dimensions
|
||||
|
||||
// Time
|
||||
mNcFile.getDimension( "time", &count, &ncid );
|
||||
ncFile.getDimension( "time", &count, &ncid );
|
||||
dims.setDimension( CFDimensions::Time, count, ncid );
|
||||
|
||||
return dims;
|
||||
}
|
||||
|
||||
void MDAL::Loader3Di::populateFacesAndVertices( Vertices &vertices, Faces &faces )
|
||||
void MDAL::Driver3Di::populateFacesAndVertices( Vertices &vertices, Faces &faces )
|
||||
{
|
||||
assert( vertices.empty() );
|
||||
size_t faceCount = mDimensions.size( CFDimensions::Face2D );
|
||||
@ -101,7 +109,7 @@ void MDAL::Loader3Di::populateFacesAndVertices( Vertices &vertices, Faces &faces
|
||||
mDimensions.setDimension( CFDimensions::Vertex2D, vertices.size() );
|
||||
}
|
||||
|
||||
void MDAL::Loader3Di::addBedElevation( MDAL::Mesh *mesh )
|
||||
void MDAL::Driver3Di::addBedElevation( MDAL::Mesh *mesh )
|
||||
{
|
||||
assert( mesh );
|
||||
if ( 0 == mesh->facesCount() )
|
||||
@ -139,12 +147,12 @@ void MDAL::Loader3Di::addBedElevation( MDAL::Mesh *mesh )
|
||||
mesh->datasetGroups.push_back( group );
|
||||
}
|
||||
|
||||
std::string MDAL::Loader3Di::getCoordinateSystemVariableName()
|
||||
std::string MDAL::Driver3Di::getCoordinateSystemVariableName()
|
||||
{
|
||||
return "projected_coordinate_system";
|
||||
}
|
||||
|
||||
std::set<std::string> MDAL::Loader3Di::ignoreNetCDFVariables()
|
||||
std::set<std::string> MDAL::Driver3Di::ignoreNetCDFVariables()
|
||||
{
|
||||
std::set<std::string> ignore_variables;
|
||||
|
||||
@ -178,13 +186,13 @@ std::set<std::string> MDAL::Loader3Di::ignoreNetCDFVariables()
|
||||
return ignore_variables;
|
||||
}
|
||||
|
||||
std::string MDAL::Loader3Di::nameSuffix( MDAL::CFDimensions::Type type )
|
||||
std::string MDAL::Driver3Di::nameSuffix( MDAL::CFDimensions::Type type )
|
||||
{
|
||||
MDAL_UNUSED( type );
|
||||
return "";
|
||||
}
|
||||
|
||||
void MDAL::Loader3Di::parseNetCDFVariableMetadata( int varid, const std::string &variableName, std::string &name, bool *is_vector, bool *is_x )
|
||||
void MDAL::Driver3Di::parseNetCDFVariableMetadata( int varid, const std::string &variableName, std::string &name, bool *is_vector, bool *is_x )
|
||||
{
|
||||
*is_vector = false;
|
||||
*is_x = true;
|
||||
|
12
external/mdal/frmts/mdal_3di.hpp
vendored
12
external/mdal/frmts/mdal_3di.hpp
vendored
@ -11,12 +11,13 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "mdal_cf.hpp"
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
|
||||
/**
|
||||
* Loader of 3Di file format.
|
||||
* Driver of 3Di file format.
|
||||
*
|
||||
* The result 3Di NetCDF file is based on CF-conventions with some additions.
|
||||
* It is unstructured grid with data stored in NetCDF/HDF5 file format.
|
||||
@ -35,14 +36,15 @@ namespace MDAL
|
||||
*
|
||||
* The 1D Mesh is present too, but not parsed yet.
|
||||
*/
|
||||
class Loader3Di: public LoaderCF
|
||||
class Driver3Di: public DriverCF
|
||||
{
|
||||
public:
|
||||
Loader3Di( const std::string &fileName );
|
||||
~Loader3Di() override = default;
|
||||
Driver3Di();
|
||||
~Driver3Di() override = default;
|
||||
Driver3Di *create() override;
|
||||
|
||||
private:
|
||||
CFDimensions populateDimensions() override;
|
||||
CFDimensions populateDimensions( const NetCDFFile &ncFile ) override;
|
||||
void populateFacesAndVertices( Vertices &vertices, Faces &faces ) override;
|
||||
void addBedElevation( Mesh *mesh ) override;
|
||||
std::string getCoordinateSystemVariableName() override;
|
||||
|
42
external/mdal/frmts/mdal_ascii_dat.cpp
vendored
42
external/mdal/frmts/mdal_ascii_dat.cpp
vendored
@ -23,11 +23,42 @@
|
||||
|
||||
#define EXIT_WITH_ERROR(error) { if (status) *status = (error); return; }
|
||||
|
||||
MDAL::LoaderAsciiDat::LoaderAsciiDat( const std::string &datFile ):
|
||||
mDatFile( datFile )
|
||||
MDAL::DriverAsciiDat::DriverAsciiDat( ):
|
||||
Driver( "ASCII_DAT",
|
||||
"DAT",
|
||||
"*.dat",
|
||||
DriverType::CanReadOnlyDatasets
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
MDAL::DriverAsciiDat *MDAL::DriverAsciiDat::create()
|
||||
{
|
||||
return new DriverAsciiDat();
|
||||
}
|
||||
|
||||
MDAL::DriverAsciiDat::~DriverAsciiDat( ) = default;
|
||||
|
||||
bool MDAL::DriverAsciiDat::canRead( const std::string &uri )
|
||||
{
|
||||
std::ifstream in( uri, std::ifstream::in );
|
||||
std::string line;
|
||||
if ( !std::getline( in, line ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
line = trim( line );
|
||||
|
||||
if ( line != "DATASET" &&
|
||||
line != "SCALAR" &&
|
||||
line != "VECTOR" )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The DAT format contains "datasets" and each dataset has N-outputs. One output
|
||||
* represents data for all vertices/faces for one timestep
|
||||
@ -35,8 +66,9 @@ MDAL::LoaderAsciiDat::LoaderAsciiDat( const std::string &datFile ):
|
||||
* In MDAL we convert one output to one MDAL dataset;
|
||||
*
|
||||
*/
|
||||
void MDAL::LoaderAsciiDat::load( MDAL::Mesh *mesh, MDAL_Status *status )
|
||||
void MDAL::DriverAsciiDat::load( const std::string &datFile, MDAL::Mesh *mesh, MDAL_Status *status )
|
||||
{
|
||||
mDatFile = datFile;
|
||||
if ( status ) *status = MDAL_Status::None;
|
||||
|
||||
if ( !MDAL::fileExists( mDatFile ) )
|
||||
@ -195,7 +227,7 @@ void MDAL::LoaderAsciiDat::load( MDAL::Mesh *mesh, MDAL_Status *status )
|
||||
}
|
||||
}
|
||||
|
||||
void MDAL::LoaderAsciiDat::readVertexTimestep(
|
||||
void MDAL::DriverAsciiDat::readVertexTimestep(
|
||||
const MDAL::Mesh *mesh,
|
||||
std::shared_ptr<DatasetGroup> group,
|
||||
double t,
|
||||
@ -262,7 +294,7 @@ void MDAL::LoaderAsciiDat::readVertexTimestep(
|
||||
group->datasets.push_back( dataset );
|
||||
}
|
||||
|
||||
void MDAL::LoaderAsciiDat::readFaceTimestep(
|
||||
void MDAL::DriverAsciiDat::readFaceTimestep(
|
||||
const MDAL::Mesh *mesh,
|
||||
std::shared_ptr<DatasetGroup> group,
|
||||
double t,
|
||||
|
12
external/mdal/frmts/mdal_ascii_dat.hpp
vendored
12
external/mdal/frmts/mdal_ascii_dat.hpp
vendored
@ -15,15 +15,21 @@
|
||||
|
||||
#include "mdal_data_model.hpp"
|
||||
#include "mdal.h"
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
|
||||
class LoaderAsciiDat
|
||||
class DriverAsciiDat: public Driver
|
||||
{
|
||||
public:
|
||||
LoaderAsciiDat( const std::string &datFile );
|
||||
void load( Mesh *mesh, MDAL_Status *status );
|
||||
DriverAsciiDat();
|
||||
~DriverAsciiDat( ) override;
|
||||
DriverAsciiDat *create() override;
|
||||
|
||||
bool canRead( const std::string &uri ) override;
|
||||
void load( const std::string &datFile, Mesh *mesh, MDAL_Status *status ) override;
|
||||
|
||||
|
||||
private:
|
||||
void readVertexTimestep(
|
||||
|
34
external/mdal/frmts/mdal_binary_dat.cpp
vendored
34
external/mdal/frmts/mdal_binary_dat.cpp
vendored
@ -71,11 +71,36 @@ static bool readIStat( std::ifstream &in, int sflg, char *flag )
|
||||
return false;
|
||||
}
|
||||
|
||||
MDAL::LoaderBinaryDat::LoaderBinaryDat( const std::string &datFile ):
|
||||
mDatFile( datFile )
|
||||
MDAL::DriverBinaryDat::DriverBinaryDat():
|
||||
Driver( "BINARY_DAT",
|
||||
"Binary DAT",
|
||||
"*.dat",
|
||||
DriverType::CanReadOnlyDatasets
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
MDAL::DriverBinaryDat *MDAL::DriverBinaryDat::create()
|
||||
{
|
||||
return new DriverBinaryDat();
|
||||
}
|
||||
|
||||
MDAL::DriverBinaryDat::~DriverBinaryDat() = default;
|
||||
|
||||
bool MDAL::DriverBinaryDat::canRead( const std::string &uri )
|
||||
{
|
||||
std::ifstream in( uri, std::ifstream::in | std::ifstream::binary );
|
||||
int version;
|
||||
|
||||
if ( read( in, reinterpret_cast< char * >( &version ), 4 ) )
|
||||
return false;
|
||||
|
||||
if ( version != CT_VERSION ) // Version should be 3000
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The DAT format contains "datasets" and each dataset has N-outputs. One output
|
||||
* represents data for all vertices/faces for one timestep
|
||||
@ -86,8 +111,9 @@ MDAL::LoaderBinaryDat::LoaderBinaryDat( const std::string &datFile ):
|
||||
* In MDAL we convert one output to one MDAL dataset;
|
||||
*
|
||||
*/
|
||||
void MDAL::LoaderBinaryDat::load( MDAL::Mesh *mesh, MDAL_Status *status )
|
||||
void MDAL::DriverBinaryDat::load( const std::string &datFile, MDAL::Mesh *mesh, MDAL_Status *status )
|
||||
{
|
||||
mDatFile = datFile;
|
||||
if ( status ) *status = MDAL_Status::None;
|
||||
|
||||
if ( !MDAL::fileExists( mDatFile ) )
|
||||
@ -245,7 +271,7 @@ void MDAL::LoaderBinaryDat::load( MDAL::Mesh *mesh, MDAL_Status *status )
|
||||
}
|
||||
}
|
||||
|
||||
bool MDAL::LoaderBinaryDat::readVertexTimestep( const MDAL::Mesh *mesh,
|
||||
bool MDAL::DriverBinaryDat::readVertexTimestep( const MDAL::Mesh *mesh,
|
||||
std::shared_ptr<DatasetGroup> group,
|
||||
std::shared_ptr<DatasetGroup> groupMax,
|
||||
double time,
|
||||
|
11
external/mdal/frmts/mdal_binary_dat.hpp
vendored
11
external/mdal/frmts/mdal_binary_dat.hpp
vendored
@ -15,15 +15,20 @@
|
||||
|
||||
#include "mdal_data_model.hpp"
|
||||
#include "mdal.h"
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
|
||||
class LoaderBinaryDat
|
||||
class DriverBinaryDat: public Driver
|
||||
{
|
||||
public:
|
||||
LoaderBinaryDat( const std::string &datFile );
|
||||
void load( Mesh *mesh, MDAL_Status *status );
|
||||
DriverBinaryDat();
|
||||
~DriverBinaryDat( ) override;
|
||||
DriverBinaryDat *create() override;
|
||||
|
||||
bool canRead( const std::string &uri ) override;
|
||||
void load( const std::string &datFile, Mesh *mesh, MDAL_Status *status ) override;
|
||||
|
||||
private:
|
||||
bool readVertexTimestep( const Mesh *mesh,
|
||||
|
37
external/mdal/frmts/mdal_cf.cpp
vendored
37
external/mdal/frmts/mdal_cf.cpp
vendored
@ -15,7 +15,7 @@
|
||||
|
||||
#define CF_THROW_ERR throw MDAL_Status::Err_UnknownFormat
|
||||
|
||||
MDAL::cfdataset_info_map MDAL::LoaderCF::parseDatasetGroupInfo()
|
||||
MDAL::cfdataset_info_map MDAL::DriverCF::parseDatasetGroupInfo()
|
||||
{
|
||||
/*
|
||||
* list of datasets:
|
||||
@ -147,7 +147,7 @@ static void populate_vals( bool is_vector, double *vals, size_t i,
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<MDAL::Dataset> MDAL::LoaderCF::createFace2DDataset( std::shared_ptr<DatasetGroup> group, size_t ts, const MDAL::CFDatasetGroupInfo &dsi,
|
||||
std::shared_ptr<MDAL::Dataset> MDAL::DriverCF::createFace2DDataset( std::shared_ptr<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 )
|
||||
{
|
||||
@ -174,7 +174,7 @@ std::shared_ptr<MDAL::Dataset> MDAL::LoaderCF::createFace2DDataset( std::shared_
|
||||
return dataset;
|
||||
}
|
||||
|
||||
void MDAL::LoaderCF::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 */
|
||||
for ( const auto &it : dsinfo_map )
|
||||
@ -228,7 +228,7 @@ void MDAL::LoaderCF::addDatasetGroups( MDAL::Mesh *mesh, const std::vector<doubl
|
||||
}
|
||||
}
|
||||
|
||||
void MDAL::LoaderCF::parseTime( std::vector<double> × )
|
||||
void MDAL::DriverCF::parseTime( std::vector<double> × )
|
||||
{
|
||||
|
||||
size_t nTimesteps = mDimensions.size( CFDimensions::Time );
|
||||
@ -242,12 +242,29 @@ void MDAL::LoaderCF::parseTime( std::vector<double> × )
|
||||
}
|
||||
|
||||
|
||||
MDAL::LoaderCF::LoaderCF( const std::string &fileName ):
|
||||
mFileName( fileName )
|
||||
MDAL::DriverCF::DriverCF( const std::string &name,
|
||||
const std::string &longName,
|
||||
const std::string &filters ):
|
||||
Driver( name, longName, filters, DriverType::CanReadMeshAndDatasets )
|
||||
{
|
||||
}
|
||||
|
||||
void MDAL::LoaderCF::setProjection( MDAL::Mesh *mesh )
|
||||
bool MDAL::DriverCF::canRead( const std::string &uri )
|
||||
{
|
||||
try
|
||||
{
|
||||
NetCDFFile ncFile;
|
||||
ncFile.openFile( uri );
|
||||
populateDimensions( ncFile );
|
||||
}
|
||||
catch ( MDAL_Status )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MDAL::DriverCF::setProjection( MDAL::Mesh *mesh )
|
||||
{
|
||||
std::string coordinate_system_variable = getCoordinateSystemVariableName();
|
||||
|
||||
@ -287,8 +304,10 @@ void MDAL::LoaderCF::setProjection( MDAL::Mesh *mesh )
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr< MDAL::Mesh > MDAL::LoaderCF::load( MDAL_Status *status )
|
||||
std::unique_ptr< MDAL::Mesh > MDAL::DriverCF::load( const std::string &fileName, MDAL_Status *status )
|
||||
{
|
||||
mFileName = fileName;
|
||||
|
||||
if ( status ) *status = MDAL_Status::None;
|
||||
|
||||
//Dimensions dims;
|
||||
@ -300,7 +319,7 @@ std::unique_ptr< MDAL::Mesh > MDAL::LoaderCF::load( MDAL_Status *status )
|
||||
mNcFile.openFile( mFileName );
|
||||
|
||||
// Parse dimensions
|
||||
mDimensions = populateDimensions();
|
||||
mDimensions = populateDimensions( mNcFile );
|
||||
|
||||
// Create mMesh
|
||||
Faces faces;
|
||||
|
17
external/mdal/frmts/mdal_cf.hpp
vendored
17
external/mdal/frmts/mdal_cf.hpp
vendored
@ -16,6 +16,7 @@
|
||||
#include "mdal.h"
|
||||
#include "mdal_utils.hpp"
|
||||
#include "mdal_netcdf.hpp"
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
@ -66,16 +67,18 @@ namespace MDAL
|
||||
|
||||
//! NetCDF Climate and Forecast (CF) Metadata Conventions
|
||||
//! http://cfconventions.org
|
||||
class LoaderCF
|
||||
class DriverCF: public Driver
|
||||
{
|
||||
public:
|
||||
LoaderCF( const std::string &fileName );
|
||||
virtual ~LoaderCF() = default;
|
||||
|
||||
std::unique_ptr< Mesh > load( MDAL_Status *status );
|
||||
DriverCF( const std::string &name,
|
||||
const std::string &longName,
|
||||
const std::string &filters );
|
||||
virtual ~DriverCF() override = default;
|
||||
bool canRead( const std::string &uri ) override;
|
||||
std::unique_ptr< Mesh > load( const std::string &fileName, MDAL_Status *status ) override;
|
||||
|
||||
protected:
|
||||
virtual CFDimensions populateDimensions() = 0;
|
||||
virtual CFDimensions populateDimensions( const NetCDFFile &ncFile ) = 0;
|
||||
virtual void populateFacesAndVertices( Vertices &vertices, Faces &faces ) = 0;
|
||||
virtual void addBedElevation( MDAL::Mesh *mesh ) = 0;
|
||||
virtual std::string getCoordinateSystemVariableName() = 0;
|
||||
@ -100,7 +103,7 @@ namespace MDAL
|
||||
const cfdataset_info_map &dsinfo_map );
|
||||
|
||||
|
||||
const std::string mFileName;
|
||||
std::string mFileName;
|
||||
NetCDFFile mNcFile;
|
||||
CFDimensions mDimensions;
|
||||
};
|
||||
|
56
external/mdal/frmts/mdal_driver.cpp
vendored
Normal file
56
external/mdal/frmts/mdal_driver.cpp
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2018 Lutra Consulting Ltd.
|
||||
*/
|
||||
|
||||
#include "mdal_driver.hpp"
|
||||
#include "mdal_utils.hpp"
|
||||
|
||||
MDAL::Driver::Driver( const std::string &name,
|
||||
const std::string &longName,
|
||||
const std::string &filters,
|
||||
DriverType type )
|
||||
: mName( name )
|
||||
, mLongName( longName )
|
||||
, mFilters( filters )
|
||||
, mType( type )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MDAL::Driver::~Driver() = default;
|
||||
|
||||
std::string MDAL::Driver::name() const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
std::string MDAL::Driver::longName() const
|
||||
{
|
||||
return mLongName;
|
||||
}
|
||||
|
||||
std::string MDAL::Driver::filters() const
|
||||
{
|
||||
return mFilters;
|
||||
}
|
||||
|
||||
MDAL::DriverType MDAL::Driver::type() const
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
std::unique_ptr< MDAL::Mesh > MDAL::Driver::load( const std::string &uri, MDAL_Status *status )
|
||||
{
|
||||
MDAL_UNUSED( uri );
|
||||
MDAL_UNUSED( status );
|
||||
return std::unique_ptr< MDAL::Mesh >();
|
||||
}
|
||||
|
||||
void MDAL::Driver::load( const std::string &uri, Mesh *mesh, MDAL_Status *status )
|
||||
{
|
||||
MDAL_UNUSED( uri );
|
||||
MDAL_UNUSED( mesh );
|
||||
MDAL_UNUSED( status );
|
||||
return;
|
||||
}
|
53
external/mdal/frmts/mdal_driver.hpp
vendored
Normal file
53
external/mdal/frmts/mdal_driver.hpp
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
|
||||
*/
|
||||
|
||||
#ifndef MDAL_DRIVER_HPP
|
||||
#define MDAL_DRIVER_HPP
|
||||
|
||||
#include <string>
|
||||
#include "mdal_data_model.hpp"
|
||||
#include "mdal.h"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
enum DriverType
|
||||
{
|
||||
CanReadMeshAndDatasets,
|
||||
CanReadOnlyDatasets
|
||||
};
|
||||
|
||||
class Driver
|
||||
{
|
||||
public:
|
||||
Driver( const std::string &name,
|
||||
const std::string &longName,
|
||||
const std::string &filters,
|
||||
DriverType type
|
||||
);
|
||||
virtual ~Driver();
|
||||
|
||||
virtual Driver *create() = 0;
|
||||
|
||||
std::string name() const;
|
||||
std::string longName() const;
|
||||
std::string filters() const;
|
||||
DriverType type() const;
|
||||
|
||||
virtual bool canRead( const std::string &uri ) = 0;
|
||||
|
||||
// loads mesh
|
||||
virtual std::unique_ptr< Mesh > load( const std::string &uri, MDAL_Status *status );
|
||||
// loads datasets
|
||||
virtual void load( const std::string &uri, Mesh *mesh, MDAL_Status *status );
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
std::string mLongName;
|
||||
std::string mFilters;
|
||||
DriverType mType;
|
||||
};
|
||||
|
||||
} // namespace MDAL
|
||||
#endif //MDAL_DRIVER_HPP
|
695
external/mdal/frmts/mdal_flo2d.cpp
vendored
Normal file
695
external/mdal/frmts/mdal_flo2d.cpp
vendored
Normal file
@ -0,0 +1,695 @@
|
||||
/*
|
||||
MDAL - mMesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2016 Lutra Consulting
|
||||
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
|
||||
*/
|
||||
|
||||
#include "mdal_flo2d.hpp"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <iosfwd>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
#include "mdal_utils.hpp"
|
||||
#include "mdal_hdf5.hpp"
|
||||
|
||||
struct VertexCompare
|
||||
{
|
||||
bool operator()( const MDAL::Vertex &lhs, const MDAL::Vertex &rhs ) const
|
||||
{
|
||||
double resX = 0;
|
||||
resX += lhs.x * 1000000;
|
||||
resX += lhs.y * 1000;
|
||||
|
||||
double resY = 0;
|
||||
resY += rhs.x * 1000000;
|
||||
resY += rhs.y * 1000;
|
||||
|
||||
return resX < resY;
|
||||
}
|
||||
};
|
||||
|
||||
static inline bool is_nodata( double val )
|
||||
{
|
||||
return MDAL::equals( val, -9999.0, 1e-8 );
|
||||
}
|
||||
|
||||
static std::string fileNameFromDir( const std::string &mainFileName, const std::string &name )
|
||||
{
|
||||
std::string dir = MDAL::dirName( mainFileName );
|
||||
return MDAL::pathJoin( dir, name );
|
||||
}
|
||||
|
||||
static double getDouble( double val )
|
||||
{
|
||||
if ( is_nodata( val ) )
|
||||
{
|
||||
return MDAL_NAN;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
static double getDouble( const std::string &val )
|
||||
{
|
||||
if ( MDAL::isNumber( val ) )
|
||||
{
|
||||
double valF = MDAL::toDouble( val );
|
||||
return getDouble( valF );
|
||||
}
|
||||
else
|
||||
{
|
||||
return MDAL_NAN;
|
||||
}
|
||||
}
|
||||
|
||||
void MDAL::DriverFlo2D::addStaticDataset(
|
||||
bool isOnVertices,
|
||||
std::vector<double> &vals,
|
||||
const std::string &name,
|
||||
const std::string &datFileName )
|
||||
{
|
||||
std::shared_ptr<DatasetGroup> group = std::make_shared< DatasetGroup >(
|
||||
mMesh.get(),
|
||||
datFileName,
|
||||
name
|
||||
);
|
||||
group->setIsOnVertices( isOnVertices );
|
||||
group->setIsScalar( true );
|
||||
|
||||
std::shared_ptr<MDAL::MemoryDataset> dataset = std::make_shared< MemoryDataset >( group.get() );
|
||||
assert( vals.size() == dataset->valuesCount() );
|
||||
dataset->setTime( 0.0 );
|
||||
double *values = dataset->values();
|
||||
memcpy( values, vals.data(), vals.size() * sizeof( double ) );
|
||||
dataset->setStatistics( MDAL::calculateStatistics( dataset ) );
|
||||
group->datasets.push_back( dataset );
|
||||
group->setStatistics( MDAL::calculateStatistics( group ) );
|
||||
mMesh->datasetGroups.push_back( group );
|
||||
}
|
||||
|
||||
void MDAL::DriverFlo2D::parseCADPTSFile( const std::string &datFileName, std::vector<CellCenter> &cells )
|
||||
{
|
||||
std::string cadptsFile( fileNameFromDir( datFileName, "CADPTS.DAT" ) );
|
||||
if ( !MDAL::fileExists( cadptsFile ) )
|
||||
{
|
||||
throw MDAL_Status::Err_FileNotFound;
|
||||
}
|
||||
|
||||
std::ifstream cadptsStream( cadptsFile, std::ifstream::in );
|
||||
std::string line;
|
||||
// CADPTS.DAT - COORDINATES OF CELL CENTERS (ELEM NUM, X, Y)
|
||||
while ( std::getline( cadptsStream, line ) )
|
||||
{
|
||||
std::vector<std::string> lineParts = MDAL::split( line, " ", MDAL::SplitBehaviour::SkipEmptyParts );
|
||||
if ( lineParts.size() != 3 )
|
||||
{
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
CellCenter cc;
|
||||
cc.id = MDAL::toSizeT( lineParts[1] ) - 1; //numbered from 1
|
||||
cc.x = MDAL::toDouble( lineParts[1] );
|
||||
cc.y = MDAL::toDouble( lineParts[2] );
|
||||
cc.conn.resize( 4 );
|
||||
cells.push_back( cc );
|
||||
}
|
||||
}
|
||||
|
||||
void MDAL::DriverFlo2D::parseFPLAINFile( std::vector<double> &elevations,
|
||||
const std::string &datFileName,
|
||||
std::vector<CellCenter> &cells )
|
||||
{
|
||||
elevations.clear();
|
||||
// FPLAIN.DAT - CONNECTIVITY (ELEM NUM, ELEM N, ELEM E, ELEM S, ELEM W, MANNING-N, BED ELEVATION)
|
||||
std::string fplainFile( fileNameFromDir( datFileName, "FPLAIN.DAT" ) );
|
||||
if ( !MDAL::fileExists( fplainFile ) )
|
||||
{
|
||||
throw MDAL_Status::Err_FileNotFound;
|
||||
}
|
||||
|
||||
std::ifstream fplainStream( fplainFile, std::ifstream::in );
|
||||
std::string line;
|
||||
|
||||
while ( std::getline( fplainStream, line ) )
|
||||
{
|
||||
std::vector<std::string> lineParts = MDAL::split( line, " ", MDAL::SplitBehaviour::SkipEmptyParts );
|
||||
if ( lineParts.size() != 7 )
|
||||
{
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
size_t cc_i = MDAL::toSizeT( lineParts[0] ) - 1; //numbered from 1
|
||||
for ( size_t j = 0; j < 4; ++j )
|
||||
{
|
||||
cells[cc_i].conn[j] = MDAL::toInt( lineParts[j + 1] ) - 1; //numbered from 1, 0 boundary Vertex
|
||||
}
|
||||
elevations.push_back( MDAL::toDouble( lineParts[6] ) );
|
||||
}
|
||||
}
|
||||
|
||||
static void addDatasetToGroup( std::shared_ptr<MDAL::DatasetGroup> group, std::shared_ptr<MDAL::MemoryDataset> dataset )
|
||||
{
|
||||
if ( group && dataset && dataset->valuesCount() > 0 )
|
||||
{
|
||||
dataset->setStatistics( MDAL::calculateStatistics( dataset ) );
|
||||
group->datasets.push_back( dataset );
|
||||
}
|
||||
}
|
||||
|
||||
void MDAL::DriverFlo2D::parseTIMDEPFile( const std::string &datFileName, const std::vector<double> &elevations )
|
||||
{
|
||||
// TIMDEP.OUT
|
||||
// this file is optional, so if not present, reading is skipped
|
||||
// time (separate line)
|
||||
// For every Vertex:
|
||||
// FLO2D: ELEM NUMber (indexed from 1), depth, velocity, velocity x, velocity y
|
||||
// FLO2DPro: ELEM NUMber (indexed from 1), depth, velocity, velocity x, velocity y, water surface elevation
|
||||
std::string inFile( fileNameFromDir( datFileName, "TIMDEP.OUT" ) );
|
||||
if ( !MDAL::fileExists( inFile ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::ifstream inStream( inFile, std::ifstream::in );
|
||||
std::string line;
|
||||
|
||||
size_t nVertexs = mMesh->verticesCount();
|
||||
size_t ntimes = 0;
|
||||
|
||||
double time = 0.0;
|
||||
size_t face_idx = 0;
|
||||
|
||||
std::shared_ptr<DatasetGroup> depthDsGroup = std::make_shared< DatasetGroup >(
|
||||
mMesh.get(),
|
||||
datFileName,
|
||||
"Depth"
|
||||
);
|
||||
depthDsGroup->setIsOnVertices( false );
|
||||
depthDsGroup->setIsScalar( true );
|
||||
|
||||
|
||||
std::shared_ptr<DatasetGroup> waterLevelDsGroup = std::make_shared< DatasetGroup >(
|
||||
mMesh.get(),
|
||||
datFileName,
|
||||
"Water Level"
|
||||
);
|
||||
waterLevelDsGroup->setIsOnVertices( false );
|
||||
waterLevelDsGroup->setIsScalar( true );
|
||||
|
||||
std::shared_ptr<DatasetGroup> flowDsGroup = std::make_shared< DatasetGroup >(
|
||||
mMesh.get(),
|
||||
datFileName,
|
||||
"Velocity"
|
||||
);
|
||||
flowDsGroup->setIsOnVertices( false );
|
||||
flowDsGroup->setIsScalar( false );
|
||||
|
||||
std::shared_ptr<MDAL::MemoryDataset> flowDataset;
|
||||
std::shared_ptr<MDAL::MemoryDataset> depthDataset;
|
||||
std::shared_ptr<MDAL::MemoryDataset> waterLevelDataset;
|
||||
|
||||
while ( std::getline( inStream, line ) )
|
||||
{
|
||||
std::vector<std::string> lineParts = MDAL::split( line, " ", MDAL::SplitBehaviour::SkipEmptyParts );
|
||||
if ( lineParts.size() == 1 )
|
||||
{
|
||||
time = MDAL::toDouble( line );
|
||||
ntimes++;
|
||||
|
||||
if ( depthDataset ) addDatasetToGroup( depthDsGroup, depthDataset );
|
||||
if ( flowDataset ) addDatasetToGroup( flowDsGroup, flowDataset );
|
||||
if ( waterLevelDataset ) addDatasetToGroup( waterLevelDsGroup, waterLevelDataset );
|
||||
|
||||
depthDataset = std::make_shared< MemoryDataset >( depthDsGroup.get() );
|
||||
flowDataset = std::make_shared< MemoryDataset >( flowDsGroup.get() );
|
||||
waterLevelDataset = std::make_shared< MemoryDataset >( waterLevelDsGroup.get() );
|
||||
|
||||
depthDataset->setTime( time );
|
||||
flowDataset->setTime( time );
|
||||
waterLevelDataset->setTime( time );
|
||||
|
||||
face_idx = 0;
|
||||
|
||||
}
|
||||
else if ( ( lineParts.size() == 5 ) || ( lineParts.size() == 6 ) )
|
||||
{
|
||||
// new Vertex for time
|
||||
if ( !depthDataset || !flowDataset || !waterLevelDataset ) throw MDAL_Status::Err_UnknownFormat;
|
||||
if ( face_idx == nVertexs ) throw MDAL_Status::Err_IncompatibleMesh;
|
||||
|
||||
// this is magnitude: getDouble(lineParts[2]);
|
||||
flowDataset->values()[2 * face_idx] = getDouble( lineParts[3] );
|
||||
flowDataset->values()[2 * face_idx + 1] = getDouble( lineParts[4] );
|
||||
|
||||
double depth = getDouble( lineParts[1] );
|
||||
depthDataset->values()[face_idx] = depth;
|
||||
|
||||
if ( !is_nodata( depth ) ) depth += elevations[face_idx];
|
||||
waterLevelDataset->values()[face_idx] = depth;
|
||||
|
||||
face_idx ++;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
}
|
||||
|
||||
if ( depthDataset ) addDatasetToGroup( depthDsGroup, depthDataset );
|
||||
if ( flowDataset ) addDatasetToGroup( flowDsGroup, flowDataset );
|
||||
if ( waterLevelDataset ) addDatasetToGroup( waterLevelDsGroup, waterLevelDataset );
|
||||
|
||||
depthDsGroup->setStatistics( MDAL::calculateStatistics( depthDsGroup ) );
|
||||
flowDsGroup->setStatistics( MDAL::calculateStatistics( flowDsGroup ) );
|
||||
waterLevelDsGroup->setStatistics( MDAL::calculateStatistics( waterLevelDsGroup ) );
|
||||
|
||||
mMesh->datasetGroups.push_back( depthDsGroup );
|
||||
mMesh->datasetGroups.push_back( flowDsGroup );
|
||||
mMesh->datasetGroups.push_back( waterLevelDsGroup );
|
||||
}
|
||||
|
||||
|
||||
void MDAL::DriverFlo2D::parseDEPTHFile( const std::string &datFileName, const std::vector<double> &elevations )
|
||||
{
|
||||
// this file is optional, so if not present, reading is skipped
|
||||
std::string depthFile( fileNameFromDir( datFileName, "DEPTH.OUT" ) );
|
||||
if ( !MDAL::fileExists( depthFile ) )
|
||||
{
|
||||
return; //optional file
|
||||
}
|
||||
|
||||
std::ifstream depthStream( depthFile, std::ifstream::in );
|
||||
std::string line;
|
||||
|
||||
size_t nVertices = mMesh->verticesCount();
|
||||
std::vector<double> maxDepth( nVertices );
|
||||
std::vector<double> maxWaterLevel( nVertices );
|
||||
|
||||
size_t vertex_idx = 0;
|
||||
|
||||
// DEPTH.OUT - COORDINATES (ELEM NUM, X, Y, MAX DEPTH)
|
||||
while ( std::getline( depthStream, line ) )
|
||||
{
|
||||
if ( vertex_idx == nVertices ) throw MDAL_Status::Err_IncompatibleMesh;
|
||||
|
||||
std::vector<std::string> lineParts = MDAL::split( line, " ", MDAL::SplitBehaviour::SkipEmptyParts );
|
||||
if ( lineParts.size() != 4 )
|
||||
{
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
|
||||
double val = getDouble( lineParts[3] );
|
||||
maxDepth[vertex_idx] = val;
|
||||
|
||||
//water level
|
||||
if ( !is_nodata( val ) ) val += elevations[vertex_idx];
|
||||
maxWaterLevel[vertex_idx] = val;
|
||||
|
||||
|
||||
vertex_idx++;
|
||||
}
|
||||
|
||||
addStaticDataset( true, maxDepth, "Depth/Maximums", datFileName );
|
||||
addStaticDataset( true, maxWaterLevel, "Water Level/Maximums", datFileName );
|
||||
}
|
||||
|
||||
|
||||
void MDAL::DriverFlo2D::parseVELFPVELOCFile( const std::string &datFileName )
|
||||
{
|
||||
// these files are optional, so if not present, reading is skipped
|
||||
size_t nVertices = mMesh->verticesCount();
|
||||
std::vector<double> maxVel( nVertices );
|
||||
|
||||
{
|
||||
std::string velocityFile( fileNameFromDir( datFileName, "VELFP.OUT" ) );
|
||||
if ( !MDAL::fileExists( velocityFile ) )
|
||||
{
|
||||
return; //optional file
|
||||
}
|
||||
|
||||
std::ifstream velocityStream( velocityFile, std::ifstream::in );
|
||||
std::string line;
|
||||
|
||||
size_t vertex_idx = 0;
|
||||
|
||||
// VELFP.OUT - COORDINATES (ELEM NUM, X, Y, MAX VEL) - Maximum floodplain flow velocity;
|
||||
while ( std::getline( velocityStream, line ) )
|
||||
{
|
||||
if ( vertex_idx == nVertices ) throw MDAL_Status::Err_IncompatibleMesh;
|
||||
|
||||
std::vector<std::string> lineParts = MDAL::split( line, " ", MDAL::SplitBehaviour::SkipEmptyParts );
|
||||
if ( lineParts.size() != 4 )
|
||||
{
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
|
||||
double val = getDouble( lineParts[3] );
|
||||
maxVel[vertex_idx] = val;
|
||||
|
||||
vertex_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::string velocityFile( fileNameFromDir( datFileName, "VELOC.OUT" ) );
|
||||
if ( !MDAL::fileExists( velocityFile ) )
|
||||
{
|
||||
return; //optional file
|
||||
}
|
||||
|
||||
std::ifstream velocityStream( velocityFile, std::ifstream::in );
|
||||
std::string line;
|
||||
|
||||
size_t vertex_idx = 0;
|
||||
|
||||
// VELOC.OUT - COORDINATES (ELEM NUM, X, Y, MAX VEL) - Maximum channel flow velocity
|
||||
while ( std::getline( velocityStream, line ) )
|
||||
{
|
||||
if ( vertex_idx == nVertices ) throw MDAL_Status::Err_IncompatibleMesh;
|
||||
|
||||
std::vector<std::string> lineParts = MDAL::split( line, " ", MDAL::SplitBehaviour::SkipEmptyParts );
|
||||
if ( lineParts.size() != 4 )
|
||||
{
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
|
||||
double val = getDouble( lineParts[3] );
|
||||
if ( !is_nodata( val ) ) // overwrite value from VELFP if it is not 0
|
||||
{
|
||||
maxVel[vertex_idx] = val;
|
||||
}
|
||||
|
||||
vertex_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
addStaticDataset( true, maxVel, "Velocity/Maximums", datFileName );
|
||||
}
|
||||
|
||||
double MDAL::DriverFlo2D::calcCellSize( const std::vector<CellCenter> &cells )
|
||||
{
|
||||
// find first cell that is not izolated from the others
|
||||
// and return its distance to the neighbor's cell center
|
||||
for ( size_t i = 0; i < cells.size(); ++i )
|
||||
{
|
||||
for ( size_t j = 0; j < 4; ++j )
|
||||
{
|
||||
int idx = cells[i].conn[0];
|
||||
if ( idx > -1 )
|
||||
{
|
||||
if ( ( j == 0 ) || ( j == 2 ) )
|
||||
{
|
||||
return fabs( cells[static_cast<size_t>( idx )].y - cells[i].y );
|
||||
}
|
||||
else
|
||||
{
|
||||
return fabs( cells[static_cast<size_t>( idx )].x - cells[i].x );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw MDAL_Status::Err_IncompatibleMesh;
|
||||
}
|
||||
|
||||
MDAL::Vertex MDAL::DriverFlo2D::createVertex( size_t position, double half_cell_size, const CellCenter &cell )
|
||||
{
|
||||
MDAL::Vertex n;
|
||||
n.x = cell.x;
|
||||
n.y = cell.y;
|
||||
|
||||
switch ( position )
|
||||
{
|
||||
case 0:
|
||||
n.x += half_cell_size;
|
||||
n.y -= half_cell_size;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
n.x += half_cell_size;
|
||||
n.y += half_cell_size;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
n.x -= half_cell_size;
|
||||
n.y += half_cell_size;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
n.x -= half_cell_size;
|
||||
n.y -= half_cell_size;
|
||||
break;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void MDAL::DriverFlo2D::createMesh( const std::vector<CellCenter> &cells, double half_cell_size )
|
||||
{
|
||||
// Create all Faces from cell centers.
|
||||
// Vertexs must be also created, they are not stored in FLO-2D files
|
||||
// try to reuse Vertexs already created for other Faces by usage of unique_Vertexs set.
|
||||
Faces faces;
|
||||
Vertices vertices;
|
||||
std::map<Vertex, size_t, VertexCompare> unique_vertices; //vertex -> id
|
||||
size_t vertex_idx = 0;
|
||||
|
||||
for ( size_t i = 0; i < cells.size(); ++i )
|
||||
{
|
||||
Face e( 4 );
|
||||
|
||||
for ( size_t position = 0; position < 4; ++position )
|
||||
{
|
||||
Vertex n = createVertex( position, half_cell_size, cells[i] );
|
||||
const auto iter = unique_vertices.find( n );
|
||||
if ( iter == unique_vertices.end() )
|
||||
{
|
||||
unique_vertices[n] = vertex_idx;
|
||||
vertices.push_back( n );
|
||||
e[position] = vertex_idx;
|
||||
++vertex_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
e[position] = iter->second;
|
||||
}
|
||||
}
|
||||
|
||||
faces.push_back( e );
|
||||
}
|
||||
|
||||
mMesh.reset(
|
||||
new MemoryMesh(
|
||||
vertices.size(),
|
||||
faces.size(),
|
||||
4, //maximum quads
|
||||
computeExtent( vertices ),
|
||||
mDatFileName
|
||||
)
|
||||
);
|
||||
mMesh->faces = faces;
|
||||
mMesh->vertices = vertices;
|
||||
}
|
||||
|
||||
bool MDAL::DriverFlo2D::isFlo2DFile( const std::string &fileName )
|
||||
{
|
||||
std::vector<std::string> required_files =
|
||||
{
|
||||
"CADPTS.DAT",
|
||||
"FPLAIN.DAT"
|
||||
};
|
||||
|
||||
for ( const std::string &str : required_files )
|
||||
{
|
||||
std::string fn( fileNameFromDir( fileName, str ) );
|
||||
if ( !fileExists( fn ) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MDAL::DriverFlo2D::parseHDF5Datasets( const std::string &datFileName )
|
||||
{
|
||||
//return true on error
|
||||
|
||||
size_t nFaces = mMesh->facesCount();
|
||||
|
||||
std::string timedepFileName = fileNameFromDir( datFileName, "TIMDEP.HDF5" );
|
||||
if ( !fileExists( timedepFileName ) ) return true;
|
||||
|
||||
HdfFile file( timedepFileName );
|
||||
if ( !file.isValid() ) return true;
|
||||
|
||||
HdfGroup timedataGroup = file.group( "TIMDEP NETCDF OUTPUT RESULTS" );
|
||||
if ( !timedataGroup.isValid() ) return true;
|
||||
|
||||
std::vector<std::string> groupNames = timedataGroup.groups();
|
||||
|
||||
for ( const std::string &grpName : groupNames )
|
||||
{
|
||||
HdfGroup grp = timedataGroup.group( grpName );
|
||||
if ( !grp.isValid() ) return true;
|
||||
|
||||
HdfAttribute groupType = grp.attribute( "Grouptype" );
|
||||
if ( !groupType.isValid() ) return true;
|
||||
|
||||
/* Min and Max arrays in TIMDEP.HDF5 files have dimensions 1xntimesteps .
|
||||
HdfDataset minDs = grp.dataset("Mins");
|
||||
if (!minDs.isValid()) return true;
|
||||
|
||||
HdfDataset maxDs = grp.dataset("Maxs");
|
||||
if (!maxDs.isValid()) return true;
|
||||
*/
|
||||
|
||||
HdfDataset timesDs = grp.dataset( "Times" );
|
||||
if ( !timesDs.isValid() ) return true;
|
||||
size_t timesteps = timesDs.elementCount();
|
||||
|
||||
HdfDataset valuesDs = grp.dataset( "Values" );
|
||||
if ( !valuesDs.isValid() ) return true;
|
||||
|
||||
bool isVector = MDAL::contains( groupType.readString(), "vector", ContainsBehaviour::CaseInsensitive );
|
||||
|
||||
// Some sanity checks
|
||||
size_t expectedSize = mMesh->facesCount() * timesteps;
|
||||
if ( isVector ) expectedSize *= 2;
|
||||
if ( valuesDs.elementCount() != expectedSize ) return true;
|
||||
|
||||
// Read data
|
||||
std::vector<double> times = timesDs.readArrayDouble();
|
||||
std::vector<float> values = valuesDs.readArray();
|
||||
|
||||
// Create dataset now
|
||||
std::shared_ptr<DatasetGroup> ds = std::make_shared< DatasetGroup >(
|
||||
mMesh.get(),
|
||||
datFileName,
|
||||
grpName
|
||||
);
|
||||
ds->setIsOnVertices( false );
|
||||
ds->setIsScalar( !isVector );
|
||||
|
||||
for ( size_t ts = 0; ts < timesteps; ++ts )
|
||||
{
|
||||
std::shared_ptr< MemoryDataset > output = std::make_shared< MemoryDataset >( ds.get() );
|
||||
output->setTime( times[ts] );
|
||||
|
||||
if ( isVector )
|
||||
{
|
||||
// vector
|
||||
for ( size_t i = 0; i < nFaces; ++i )
|
||||
{
|
||||
size_t idx = 2 * ( ts * nFaces + i );
|
||||
double x = getDouble( static_cast<double>( values[idx] ) );
|
||||
double y = getDouble( static_cast<double>( values[idx + 1] ) );
|
||||
output->values()[2 * i] = x;
|
||||
output->values()[2 * i + 1] = y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// scalar
|
||||
for ( size_t i = 0; i < nFaces; ++i )
|
||||
{
|
||||
size_t idx = ts * nFaces + i;
|
||||
double val = getDouble( static_cast<double>( values[idx] ) );
|
||||
output->values()[i] = val;
|
||||
}
|
||||
}
|
||||
addDatasetToGroup( ds, output );
|
||||
}
|
||||
|
||||
// TODO use mins & maxs arrays
|
||||
ds->setStatistics( MDAL::calculateStatistics( ds ) );
|
||||
mMesh->datasetGroups.push_back( ds );
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MDAL::DriverFlo2D::parseOUTDatasets( const std::string &datFileName, const std::vector<double> &elevations )
|
||||
{
|
||||
// Create Depth and Velocity datasets Time varying datasets
|
||||
parseTIMDEPFile( datFileName, elevations );
|
||||
|
||||
// Maximum Depth and Water Level
|
||||
parseDEPTHFile( datFileName, elevations );
|
||||
|
||||
// Maximum Velocity
|
||||
parseVELFPVELOCFile( datFileName );
|
||||
}
|
||||
|
||||
MDAL::DriverFlo2D::DriverFlo2D()
|
||||
: Driver(
|
||||
"FLO2D",
|
||||
"Flo2D",
|
||||
"*.nc",
|
||||
DriverType::CanReadMeshAndDatasets )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MDAL::DriverFlo2D *MDAL::DriverFlo2D::create()
|
||||
{
|
||||
return new DriverFlo2D();
|
||||
}
|
||||
|
||||
bool MDAL::DriverFlo2D::canRead( const std::string &uri )
|
||||
{
|
||||
std::string cadptsFile( fileNameFromDir( uri, "CADPTS.DAT" ) );
|
||||
if ( !MDAL::fileExists( cadptsFile ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string fplainFile( fileNameFromDir( uri, "FPLAIN.DAT" ) );
|
||||
if ( !MDAL::fileExists( fplainFile ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr< MDAL::Mesh > MDAL::DriverFlo2D::load( const std::string &resultsFile, MDAL_Status *status )
|
||||
{
|
||||
mDatFileName = resultsFile;
|
||||
if ( status ) *status = MDAL_Status::None;
|
||||
mMesh.reset();
|
||||
std::vector<CellCenter> cells;
|
||||
|
||||
try
|
||||
{
|
||||
// Parse mMesh info
|
||||
parseCADPTSFile( mDatFileName, cells );
|
||||
std::vector<double> elevations;
|
||||
parseFPLAINFile( elevations, mDatFileName, cells );
|
||||
double cell_size = calcCellSize( cells );
|
||||
|
||||
// Create mMesh
|
||||
createMesh( cells, cell_size / 2.0 );
|
||||
|
||||
// create output for bed elevation
|
||||
addStaticDataset( false, elevations, "Bed Elevation", mDatFileName );
|
||||
|
||||
if ( parseHDF5Datasets( mDatFileName ) )
|
||||
{
|
||||
// some problem with HDF5 data, try text files
|
||||
parseOUTDatasets( mDatFileName, elevations );
|
||||
}
|
||||
}
|
||||
|
||||
catch ( MDAL_Status error )
|
||||
{
|
||||
if ( status ) *status = ( error );
|
||||
mMesh.reset();
|
||||
}
|
||||
|
||||
return std::unique_ptr<Mesh>( mMesh.release() );
|
||||
}
|
56
external/mdal/frmts/mdal_flo2d.hpp
vendored
Normal file
56
external/mdal/frmts/mdal_flo2d.hpp
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
|
||||
*/
|
||||
|
||||
#ifndef MDAL_FLO2D_HPP
|
||||
#define MDAL_FLO2D_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "mdal_data_model.hpp"
|
||||
#include "mdal_memory_data_model.hpp"
|
||||
#include "mdal.h"
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
class DriverFlo2D: public Driver
|
||||
{
|
||||
public:
|
||||
DriverFlo2D();
|
||||
~DriverFlo2D( ) override = default;
|
||||
DriverFlo2D *create() override;
|
||||
|
||||
bool canRead( const std::string &uri ) override;
|
||||
std::unique_ptr< Mesh > load( const std::string &resultsFile, MDAL_Status *status ) override;
|
||||
|
||||
static bool isFlo2DFile( const std::string &fileName );
|
||||
|
||||
private:
|
||||
struct CellCenter
|
||||
{
|
||||
size_t id;
|
||||
double x;
|
||||
double y;
|
||||
std::vector<int> conn; // north, east, south, west cell center index, -1 boundary Vertex
|
||||
};
|
||||
|
||||
std::unique_ptr< MDAL::MemoryMesh > mMesh;
|
||||
std::string mDatFileName;
|
||||
|
||||
void createMesh( const std::vector<CellCenter> &cells, double half_cell_size );
|
||||
void parseOUTDatasets( const std::string &datFileName, const std::vector<double> &elevations );
|
||||
bool parseHDF5Datasets( const std::string &datFileName );
|
||||
void parseVELFPVELOCFile( const std::string &datFileName );
|
||||
void parseDEPTHFile( const std::string &datFileName, const std::vector<double> &elevations );
|
||||
void parseTIMDEPFile( const std::string &datFileName, const std::vector<double> &elevations );
|
||||
void parseFPLAINFile( std::vector<double> &elevations, const std::string &datFileName, std::vector<CellCenter> &cells );
|
||||
void parseCADPTSFile( const std::string &datFileName, std::vector<CellCenter> &cells );
|
||||
void addStaticDataset( bool isOnVertices, std::vector<double> &vals, const std::string &name, const std::string &datFileName );
|
||||
static MDAL::Vertex createVertex( size_t position, double half_cell_size, const CellCenter &cell );
|
||||
static double calcCellSize( const std::vector<CellCenter> &cells );
|
||||
};
|
||||
|
||||
} // namespace MDAL
|
||||
#endif //MDAL_FLO2D_HPP
|
81
external/mdal/frmts/mdal_gdal.cpp
vendored
81
external/mdal/frmts/mdal_gdal.cpp
vendored
@ -56,7 +56,7 @@ void MDAL::GdalDataset::parseProj()
|
||||
|
||||
/******************************************************************************************************/
|
||||
|
||||
bool MDAL::LoaderGdal::meshes_equals( const MDAL::GdalDataset *ds1, const MDAL::GdalDataset *ds2 ) const
|
||||
bool MDAL::DriverGdal::meshes_equals( const MDAL::GdalDataset *ds1, const MDAL::GdalDataset *ds2 ) const
|
||||
{
|
||||
return ( ( ds1->mXSize == ds2->mXSize ) &&
|
||||
( ds1->mYSize == ds2->mYSize ) &&
|
||||
@ -70,7 +70,7 @@ bool MDAL::LoaderGdal::meshes_equals( const MDAL::GdalDataset *ds1, const MDAL::
|
||||
}
|
||||
|
||||
|
||||
bool MDAL::LoaderGdal::initVertices( Vertices &vertices )
|
||||
bool MDAL::DriverGdal::initVertices( Vertices &vertices )
|
||||
{
|
||||
Vertex *VertexsPtr = vertices.data();
|
||||
unsigned int mXSize = meshGDALDataset()->mXSize;
|
||||
@ -110,7 +110,7 @@ bool MDAL::LoaderGdal::initVertices( Vertices &vertices )
|
||||
return is_longitude_shifted;
|
||||
}
|
||||
|
||||
void MDAL::LoaderGdal::initFaces( Vertices &Vertexs, Faces &Faces, bool is_longitude_shifted )
|
||||
void MDAL::DriverGdal::initFaces( Vertices &Vertexs, Faces &Faces, bool is_longitude_shifted )
|
||||
{
|
||||
int reconnected = 0;
|
||||
unsigned int mXSize = meshGDALDataset()->mXSize;
|
||||
@ -158,21 +158,21 @@ void MDAL::LoaderGdal::initFaces( Vertices &Vertexs, Faces &Faces, bool is_longi
|
||||
assert( reconnected == 0 );
|
||||
}
|
||||
|
||||
std::string MDAL::LoaderGdal::GDALFileName( const std::string &fileName )
|
||||
std::string MDAL::DriverGdal::GDALFileName( const std::string &fileName )
|
||||
{
|
||||
return fileName;
|
||||
}
|
||||
|
||||
double MDAL::LoaderGdal::parseMetadataTime( const std::string &time_s )
|
||||
double MDAL::DriverGdal::parseMetadataTime( const std::string &time_s )
|
||||
{
|
||||
std::string time_trimmed = MDAL::trim( time_s );
|
||||
std::vector<std::string> times = MDAL::split( time_trimmed, " ", MDAL::SkipEmptyParts );
|
||||
return MDAL::toDouble( times[0] );
|
||||
}
|
||||
|
||||
MDAL::LoaderGdal::metadata_hash MDAL::LoaderGdal::parseMetadata( GDALMajorObjectH gdalObject, const char *pszDomain /* = 0 */ )
|
||||
MDAL::DriverGdal::metadata_hash MDAL::DriverGdal::parseMetadata( GDALMajorObjectH gdalObject, const char *pszDomain /* = 0 */ )
|
||||
{
|
||||
MDAL::LoaderGdal::metadata_hash meta;
|
||||
MDAL::DriverGdal::metadata_hash meta;
|
||||
char **GDALmetadata = nullptr;
|
||||
GDALmetadata = GDALGetMetadata( gdalObject, pszDomain );
|
||||
|
||||
@ -195,7 +195,7 @@ MDAL::LoaderGdal::metadata_hash MDAL::LoaderGdal::parseMetadata( GDALMajorObject
|
||||
return meta;
|
||||
}
|
||||
|
||||
void MDAL::LoaderGdal::parseRasterBands( const MDAL::GdalDataset *cfGDALDataset )
|
||||
void MDAL::DriverGdal::parseRasterBands( const MDAL::GdalDataset *cfGDALDataset )
|
||||
{
|
||||
for ( unsigned int i = 1; i <= cfGDALDataset->mNBands; ++i ) // starts with 1 .... ehm....
|
||||
{
|
||||
@ -259,7 +259,7 @@ void MDAL::LoaderGdal::parseRasterBands( const MDAL::GdalDataset *cfGDALDataset
|
||||
}
|
||||
}
|
||||
|
||||
void MDAL::LoaderGdal::addDataToOutput( GDALRasterBandH raster_band, std::shared_ptr<MemoryDataset> tos, bool is_vector, bool is_x )
|
||||
void MDAL::DriverGdal::addDataToOutput( GDALRasterBandH raster_band, std::shared_ptr<MemoryDataset> tos, bool is_vector, bool is_x )
|
||||
{
|
||||
assert( raster_band );
|
||||
|
||||
@ -318,7 +318,7 @@ void MDAL::LoaderGdal::addDataToOutput( GDALRasterBandH raster_band, std::shared
|
||||
}
|
||||
}
|
||||
|
||||
void MDAL::LoaderGdal::activateFaces( std::shared_ptr<MemoryDataset> tos )
|
||||
void MDAL::DriverGdal::activateFaces( std::shared_ptr<MemoryDataset> tos )
|
||||
{
|
||||
// only for data on vertices
|
||||
if ( !tos->group()->isOnVertices() )
|
||||
@ -358,7 +358,7 @@ void MDAL::LoaderGdal::activateFaces( std::shared_ptr<MemoryDataset> tos )
|
||||
}
|
||||
}
|
||||
|
||||
void MDAL::LoaderGdal::addDatasetGroups()
|
||||
void MDAL::DriverGdal::addDatasetGroups()
|
||||
{
|
||||
// Add dataset to mMesh
|
||||
for ( data_hash::const_iterator band = mBands.begin(); band != mBands.end(); band++ )
|
||||
@ -396,7 +396,7 @@ void MDAL::LoaderGdal::addDatasetGroups()
|
||||
}
|
||||
}
|
||||
|
||||
void MDAL::LoaderGdal::createMesh()
|
||||
void MDAL::DriverGdal::createMesh()
|
||||
{
|
||||
Vertices vertices( meshGDALDataset()->mNPoints );
|
||||
bool is_longitude_shifted = initVertices( vertices );
|
||||
@ -422,7 +422,7 @@ void MDAL::LoaderGdal::createMesh()
|
||||
}
|
||||
}
|
||||
|
||||
bool MDAL::LoaderGdal::addSrcProj()
|
||||
bool MDAL::DriverGdal::addSrcProj()
|
||||
{
|
||||
std::string proj = meshGDALDataset()->mProj;
|
||||
if ( !proj.empty() )
|
||||
@ -433,7 +433,7 @@ bool MDAL::LoaderGdal::addSrcProj()
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> MDAL::LoaderGdal::parseDatasetNames( const std::string &fileName )
|
||||
std::vector<std::string> MDAL::DriverGdal::parseDatasetNames( const std::string &fileName )
|
||||
{
|
||||
std::string gdal_name = GDALFileName( fileName );
|
||||
std::vector<std::string> ret;
|
||||
@ -464,29 +464,47 @@ std::vector<std::string> MDAL::LoaderGdal::parseDatasetNames( const std::string
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MDAL::LoaderGdal::registerDriver()
|
||||
void MDAL::DriverGdal::registerDriver()
|
||||
{
|
||||
// re-register all
|
||||
GDALAllRegister();
|
||||
// check that our driver exists
|
||||
GDALDriverH hDriver = GDALGetDriverByName( mDriverName.data() );
|
||||
GDALDriverH hDriver = GDALGetDriverByName( mGdalDriverName.data() );
|
||||
if ( !hDriver ) throw MDAL_Status::Err_MissingDriver;
|
||||
}
|
||||
|
||||
const MDAL::GdalDataset *MDAL::LoaderGdal::meshGDALDataset()
|
||||
const MDAL::GdalDataset *MDAL::DriverGdal::meshGDALDataset()
|
||||
{
|
||||
assert( gdal_datasets.size() > 0 );
|
||||
return gdal_datasets[0];
|
||||
return gdal_datasets[0].get();
|
||||
}
|
||||
|
||||
MDAL::LoaderGdal::LoaderGdal( const std::string &fileName, const std::string &driverName ):
|
||||
mFileName( fileName ),
|
||||
mDriverName( driverName ),
|
||||
MDAL::DriverGdal::DriverGdal( const std::string &name,
|
||||
const std::string &description,
|
||||
const std::string &filter,
|
||||
const std::string &gdalDriverName ):
|
||||
Driver( name, description, filter, DriverType::CanReadMeshAndDatasets ),
|
||||
mGdalDriverName( gdalDriverName ),
|
||||
mPafScanline( nullptr )
|
||||
{}
|
||||
|
||||
std::unique_ptr<MDAL::Mesh> MDAL::LoaderGdal::load( MDAL_Status *status )
|
||||
bool MDAL::DriverGdal::canRead( const std::string &uri )
|
||||
{
|
||||
try
|
||||
{
|
||||
registerDriver();
|
||||
parseDatasetNames( uri );
|
||||
}
|
||||
catch ( MDAL_Status )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<MDAL::Mesh> MDAL::DriverGdal::load( const std::string &fileName, MDAL_Status *status )
|
||||
{
|
||||
mFileName = fileName;
|
||||
if ( status ) *status = MDAL_Status::None ;
|
||||
|
||||
mPafScanline = nullptr;
|
||||
@ -505,7 +523,7 @@ std::unique_ptr<MDAL::Mesh> MDAL::LoaderGdal::load( MDAL_Status *status )
|
||||
{
|
||||
std::string gdal_dataset_name = *iter;
|
||||
// Parse dataset parameters and projection
|
||||
MDAL::GdalDataset *cfGDALDataset = new MDAL::GdalDataset;
|
||||
std::shared_ptr<MDAL::GdalDataset> cfGDALDataset = std::make_shared<MDAL::GdalDataset>();
|
||||
cfGDALDataset->init( gdal_dataset_name );
|
||||
|
||||
if ( !mMesh )
|
||||
@ -520,19 +538,14 @@ std::unique_ptr<MDAL::Mesh> MDAL::LoaderGdal::load( MDAL_Status *status )
|
||||
createMesh();
|
||||
|
||||
// Parse bands
|
||||
parseRasterBands( cfGDALDataset );
|
||||
parseRasterBands( cfGDALDataset.get() );
|
||||
|
||||
}
|
||||
else if ( meshes_equals( meshGDALDataset(), cfGDALDataset ) )
|
||||
else if ( meshes_equals( meshGDALDataset(), cfGDALDataset.get() ) )
|
||||
{
|
||||
gdal_datasets.push_back( cfGDALDataset );
|
||||
// Parse bands
|
||||
parseRasterBands( cfGDALDataset );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do not use
|
||||
delete cfGDALDataset;
|
||||
parseRasterBands( cfGDALDataset.get() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -545,10 +558,6 @@ std::unique_ptr<MDAL::Mesh> MDAL::LoaderGdal::load( MDAL_Status *status )
|
||||
mMesh.reset();
|
||||
}
|
||||
|
||||
for ( auto it = gdal_datasets.begin(); it != gdal_datasets.end(); ++it )
|
||||
{
|
||||
delete ( *it );
|
||||
}
|
||||
gdal_datasets.clear();
|
||||
|
||||
if ( mPafScanline ) delete[] mPafScanline;
|
||||
@ -562,7 +571,7 @@ std::unique_ptr<MDAL::Mesh> MDAL::LoaderGdal::load( MDAL_Status *status )
|
||||
return std::unique_ptr<Mesh>( mMesh.release() );
|
||||
}
|
||||
|
||||
void MDAL::LoaderGdal::parseBandIsVector( std::string &band_name, bool *is_vector, bool *is_x )
|
||||
void MDAL::DriverGdal::parseBandIsVector( std::string &band_name, bool *is_vector, bool *is_x )
|
||||
{
|
||||
band_name = MDAL::trim( band_name );
|
||||
|
||||
|
20
external/mdal/frmts/mdal_gdal.hpp
vendored
20
external/mdal/frmts/mdal_gdal.hpp
vendored
@ -15,6 +15,7 @@
|
||||
#include "mdal_data_model.hpp"
|
||||
#include "mdal.h"
|
||||
#include "mdal_utils.hpp"
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
@ -47,12 +48,17 @@ namespace MDAL
|
||||
void parseProj();
|
||||
};
|
||||
|
||||
class LoaderGdal
|
||||
class DriverGdal: public Driver
|
||||
{
|
||||
public:
|
||||
LoaderGdal( const std::string &fileName, const std::string &driverName );
|
||||
virtual ~LoaderGdal() = default;
|
||||
std::unique_ptr< Mesh > load( MDAL_Status *status );
|
||||
DriverGdal( const std::string &name,
|
||||
const std::string &description,
|
||||
const std::string &filter,
|
||||
const std::string &gdalDriverName );
|
||||
|
||||
virtual ~DriverGdal() override = default;
|
||||
bool canRead( const std::string &uri ) override;
|
||||
std::unique_ptr< Mesh > load( const std::string &fileName, MDAL_Status *status ) override;
|
||||
|
||||
protected:
|
||||
typedef std::map<std::string, std::string> metadata_hash; // KEY, VALUE
|
||||
@ -70,7 +76,7 @@ namespace MDAL
|
||||
private:
|
||||
typedef std::map<double, std::vector<GDALRasterBandH> > timestep_map; //TIME (sorted), [X, Y]
|
||||
typedef std::map<std::string, timestep_map > data_hash; //Data Type, TIME (sorted), [X, Y]
|
||||
typedef std::vector<GdalDataset *> gdal_datasets_vector; //GDAL (Sub)Datasets,
|
||||
typedef std::vector<std::shared_ptr<GdalDataset>> gdal_datasets_vector; //GDAL (Sub)Datasets,
|
||||
|
||||
void registerDriver();
|
||||
|
||||
@ -89,8 +95,8 @@ namespace MDAL
|
||||
void createMesh();
|
||||
void parseRasterBands( const GdalDataset *cfGDALDataset );
|
||||
|
||||
const std::string mFileName;
|
||||
const std::string mDriverName; /* GDAL driver name */
|
||||
std::string mFileName;
|
||||
const std::string mGdalDriverName; /* GDAL driver name */
|
||||
double *mPafScanline; /* temporary buffer for reading one raster line */
|
||||
std::unique_ptr< MemoryMesh > mMesh;
|
||||
gdal_datasets_vector gdal_datasets;
|
||||
|
17
external/mdal/frmts/mdal_gdal_grib.cpp
vendored
17
external/mdal/frmts/mdal_gdal_grib.cpp
vendored
@ -9,12 +9,23 @@
|
||||
#include <string>
|
||||
#include <limits>
|
||||
|
||||
MDAL::LoaderGdalGrib::LoaderGdalGrib( const std::string &gribFile )
|
||||
: MDAL::LoaderGdal( gribFile, "GRIB" ),
|
||||
MDAL::DriverGdalGrib::DriverGdalGrib( )
|
||||
: MDAL::DriverGdal(
|
||||
"GRIB",
|
||||
"GDAL Grib",
|
||||
"*.grb;;*.grb2;;*.bin;;*.grib;;*.grib1;;*.grib2"
|
||||
, "GRIB" ),
|
||||
mRefTime( std::numeric_limits<double>::min() )
|
||||
{}
|
||||
|
||||
bool MDAL::LoaderGdalGrib::parseBandInfo( const MDAL::GdalDataset *cfGDALDataset,
|
||||
MDAL::DriverGdalGrib *MDAL::DriverGdalGrib::create()
|
||||
{
|
||||
return new DriverGdalGrib();
|
||||
}
|
||||
|
||||
MDAL::DriverGdalGrib::~DriverGdalGrib() = default;
|
||||
|
||||
bool MDAL::DriverGdalGrib::parseBandInfo( const MDAL::GdalDataset *cfGDALDataset,
|
||||
const metadata_hash &metadata, std::string &band_name,
|
||||
double *time, bool *is_vector, bool *is_x
|
||||
)
|
||||
|
11
external/mdal/frmts/mdal_gdal_grib.hpp
vendored
11
external/mdal/frmts/mdal_gdal_grib.hpp
vendored
@ -6,18 +6,23 @@
|
||||
#ifndef MDAL_GDAL_GRIB_HPP
|
||||
#define MDAL_GDAL_GRIB_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "mdal_gdal.hpp"
|
||||
#include "mdal_data_model.hpp"
|
||||
#include "mdal.h"
|
||||
#include <string>
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
|
||||
class LoaderGdalGrib: public LoaderGdal
|
||||
class DriverGdalGrib: public DriverGdal
|
||||
{
|
||||
public:
|
||||
LoaderGdalGrib( const std::string &gribFile );
|
||||
DriverGdalGrib();
|
||||
~DriverGdalGrib() override;
|
||||
DriverGdalGrib *create() override;
|
||||
|
||||
private:
|
||||
bool parseBandInfo( const MDAL::GdalDataset *cfGDALDataset,
|
||||
const metadata_hash &metadata, std::string &band_name,
|
||||
|
19
external/mdal/frmts/mdal_gdal_netcdf.cpp
vendored
19
external/mdal/frmts/mdal_gdal_netcdf.cpp
vendored
@ -6,13 +6,22 @@
|
||||
#include "mdal_gdal_netcdf.hpp"
|
||||
#include "mdal_utils.hpp"
|
||||
|
||||
MDAL::LoaderGdalNetCDF::LoaderGdalNetCDF( const std::string &netCDFFile )
|
||||
: MDAL::LoaderGdal( netCDFFile, "GRIB" )
|
||||
MDAL::DriverGdalNetCDF::DriverGdalNetCDF()
|
||||
: MDAL::DriverGdal(
|
||||
"NETCDF",
|
||||
"GDAL NetCDF",
|
||||
"*.nc"
|
||||
, "GRIB" )
|
||||
, mTimeDiv( 1.0 )
|
||||
{
|
||||
}
|
||||
|
||||
std::string MDAL::LoaderGdalNetCDF::GDALFileName( const std::string &fileName )
|
||||
MDAL::DriverGdalNetCDF *MDAL::DriverGdalNetCDF::create()
|
||||
{
|
||||
return new DriverGdalNetCDF();
|
||||
}
|
||||
|
||||
std::string MDAL::DriverGdalNetCDF::GDALFileName( const std::string &fileName )
|
||||
{
|
||||
#ifdef WIN32
|
||||
// Force usage of the predefined GDAL driver
|
||||
@ -24,7 +33,7 @@ std::string MDAL::LoaderGdalNetCDF::GDALFileName( const std::string &fileName )
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MDAL::LoaderGdalNetCDF::parseBandInfo( const MDAL::GdalDataset *cfGDALDataset, const MDAL::LoaderGdal::metadata_hash &metadata, std::string &band_name, double *time, bool *is_vector, bool *is_x )
|
||||
bool MDAL::DriverGdalNetCDF::parseBandInfo( const MDAL::GdalDataset *cfGDALDataset, const MDAL::DriverGdal::metadata_hash &metadata, std::string &band_name, double *time, bool *is_vector, bool *is_x )
|
||||
{
|
||||
MDAL_UNUSED( cfGDALDataset );
|
||||
|
||||
@ -67,7 +76,7 @@ bool MDAL::LoaderGdalNetCDF::parseBandInfo( const MDAL::GdalDataset *cfGDALDatas
|
||||
return false; // SUCCESS
|
||||
}
|
||||
|
||||
void MDAL::LoaderGdalNetCDF::parseGlobals( const MDAL::LoaderGdal::metadata_hash &metadata )
|
||||
void MDAL::DriverGdalNetCDF::parseGlobals( const MDAL::DriverGdal::metadata_hash &metadata )
|
||||
{
|
||||
metadata_hash::const_iterator iter = metadata.find( "time#units" );
|
||||
if ( iter != metadata.end() )
|
||||
|
11
external/mdal/frmts/mdal_gdal_netcdf.hpp
vendored
11
external/mdal/frmts/mdal_gdal_netcdf.hpp
vendored
@ -6,18 +6,23 @@
|
||||
#ifndef MDAL_GDAL_NETCDF_HPP
|
||||
#define MDAL_GDAL_NETCDF_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "mdal_gdal.hpp"
|
||||
#include "mdal_data_model.hpp"
|
||||
#include "mdal.h"
|
||||
#include <string>
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
|
||||
class LoaderGdalNetCDF: public LoaderGdal
|
||||
class DriverGdalNetCDF: public DriverGdal
|
||||
{
|
||||
public:
|
||||
LoaderGdalNetCDF( const std::string &netCDFFile );
|
||||
DriverGdalNetCDF();
|
||||
~DriverGdalNetCDF( ) override = default;
|
||||
DriverGdalNetCDF *create() override;
|
||||
|
||||
private:
|
||||
std::string GDALFileName( const std::string &fileName ) override;
|
||||
bool parseBandInfo( const MDAL::GdalDataset *cfGDALDataset,
|
||||
|
528
external/mdal/frmts/mdal_hec2d.cpp
vendored
Normal file
528
external/mdal/frmts/mdal_hec2d.cpp
vendored
Normal file
@ -0,0 +1,528 @@
|
||||
/*
|
||||
MDAL - mMesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2016 Lutra Consulting
|
||||
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <iterator>
|
||||
#include "assert.h"
|
||||
|
||||
#include "mdal_hec2d.hpp"
|
||||
#include "mdal_hdf5.hpp"
|
||||
#include "mdal_utils.hpp"
|
||||
|
||||
static HdfFile openHdfFile( const std::string &fileName )
|
||||
{
|
||||
HdfFile file( fileName );
|
||||
if ( !file.isValid() )
|
||||
{
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
static HdfGroup openHdfGroup( const HdfFile &hdfFile, const std::string &name )
|
||||
{
|
||||
HdfGroup grp = hdfFile.group( name );
|
||||
if ( !grp.isValid() )
|
||||
{
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
return grp;
|
||||
}
|
||||
|
||||
static HdfGroup openHdfGroup( const HdfGroup &hdfGroup, const std::string &name )
|
||||
{
|
||||
HdfGroup grp = hdfGroup.group( name );
|
||||
if ( !grp.isValid() )
|
||||
{
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
return grp;
|
||||
}
|
||||
|
||||
static HdfDataset openHdfDataset( const HdfGroup &hdfGroup, const std::string &name )
|
||||
{
|
||||
HdfDataset dsFileType = hdfGroup.dataset( name );
|
||||
if ( !dsFileType.isValid() )
|
||||
{
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
return dsFileType;
|
||||
}
|
||||
|
||||
|
||||
static std::string openHdfAttribute( const HdfFile &hdfFile, const std::string &name )
|
||||
{
|
||||
HdfAttribute attr = hdfFile.attribute( name );
|
||||
if ( !attr.isValid() )
|
||||
{
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
return attr.readString();
|
||||
}
|
||||
|
||||
static HdfGroup getBaseOutputGroup( const HdfFile &hdfFile )
|
||||
{
|
||||
HdfGroup gResults = openHdfGroup( hdfFile, "Results" );
|
||||
HdfGroup gUnsteady = openHdfGroup( gResults, "Unsteady" );
|
||||
HdfGroup gOutput = openHdfGroup( gUnsteady, "Output" );
|
||||
HdfGroup gOBlocks = openHdfGroup( gOutput, "Output Blocks" );
|
||||
HdfGroup gBaseO = openHdfGroup( gOBlocks, "Base Output" );
|
||||
return gBaseO;
|
||||
}
|
||||
|
||||
static HdfGroup get2DFlowAreasGroup( const HdfFile &hdfFile, const std::string loc )
|
||||
{
|
||||
HdfGroup gBaseO = getBaseOutputGroup( hdfFile );
|
||||
HdfGroup gLoc = openHdfGroup( gBaseO, loc );
|
||||
HdfGroup g2DFlowRes = openHdfGroup( gLoc, "2D Flow Areas" );
|
||||
return g2DFlowRes;
|
||||
}
|
||||
|
||||
static std::vector<float> readTimes( const HdfFile &hdfFile )
|
||||
{
|
||||
HdfGroup gBaseO = getBaseOutputGroup( hdfFile );
|
||||
HdfGroup gUnsteadTS = openHdfGroup( gBaseO, "Unsteady Time Series" );
|
||||
HdfDataset dsTimes = openHdfDataset( gUnsteadTS, "Time" );
|
||||
std::vector<float> times = dsTimes.readArray();
|
||||
return times;
|
||||
}
|
||||
|
||||
static std::vector<int> readFace2Cells( const HdfFile &hdfFile, const std::string &flowAreaName, size_t *nFaces )
|
||||
{
|
||||
// First read face to node mapping
|
||||
HdfGroup gGeom = openHdfGroup( hdfFile, "Geometry" );
|
||||
HdfGroup gGeom2DFlowAreas = openHdfGroup( gGeom, "2D Flow Areas" );
|
||||
HdfGroup gArea = openHdfGroup( gGeom2DFlowAreas, flowAreaName );
|
||||
HdfDataset dsFace2Cells = openHdfDataset( gArea, "Faces Cell Indexes" );
|
||||
|
||||
std::vector<hsize_t> fdims = dsFace2Cells.dims();
|
||||
std::vector<int> face2Cells = dsFace2Cells.readArrayInt(); //2x nFaces
|
||||
|
||||
*nFaces = fdims[0];
|
||||
return face2Cells;
|
||||
}
|
||||
|
||||
void MDAL::DriverHec2D::readFaceOutput( const HdfFile &hdfFile,
|
||||
const HdfGroup &rootGroup,
|
||||
const std::vector<size_t> &areaElemStartIndex,
|
||||
const std::vector<std::string> &flowAreaNames,
|
||||
const std::string rawDatasetName,
|
||||
const std::string datasetName,
|
||||
const std::vector<float> × )
|
||||
{
|
||||
double eps = std::numeric_limits<double>::min();
|
||||
|
||||
std::shared_ptr<DatasetGroup> group = std::make_shared< DatasetGroup >(
|
||||
mMesh.get(),
|
||||
mFileName,
|
||||
datasetName
|
||||
);
|
||||
group->setIsOnVertices( false );
|
||||
group->setIsScalar( true );
|
||||
|
||||
std::vector<std::shared_ptr<MDAL::MemoryDataset>> datasets;
|
||||
|
||||
for ( size_t tidx = 0; tidx < times.size(); ++tidx )
|
||||
{
|
||||
std::shared_ptr<MDAL::MemoryDataset> dataset = std::make_shared< MemoryDataset >( group.get() );
|
||||
double time = static_cast<double>( times[tidx] );
|
||||
dataset->setTime( time );
|
||||
datasets.push_back( dataset );
|
||||
}
|
||||
|
||||
std::shared_ptr<MDAL::MemoryDataset> firstDataset;
|
||||
|
||||
for ( size_t nArea = 0; nArea < flowAreaNames.size(); ++nArea )
|
||||
{
|
||||
std::string flowAreaName = flowAreaNames[nArea];
|
||||
|
||||
size_t nFaces;
|
||||
std::vector<int> face2Cells = readFace2Cells( hdfFile, flowAreaName, &nFaces );
|
||||
|
||||
HdfGroup gFlowAreaRes = openHdfGroup( rootGroup, flowAreaName );
|
||||
HdfDataset dsVals = openHdfDataset( gFlowAreaRes, rawDatasetName );
|
||||
std::vector<float> vals = dsVals.readArray();
|
||||
|
||||
for ( size_t tidx = 0; tidx < times.size(); ++tidx )
|
||||
{
|
||||
std::shared_ptr<MDAL::MemoryDataset> dataset = datasets[tidx];
|
||||
double *values = dataset->values();
|
||||
|
||||
for ( size_t i = 0; i < nFaces; ++i )
|
||||
{
|
||||
size_t idx = tidx * nFaces + i;
|
||||
double val = static_cast<double>( vals[idx] ); // This is value on face!
|
||||
|
||||
if ( !std::isnan( val ) && fabs( val ) > eps ) //not nan and not 0
|
||||
{
|
||||
for ( size_t c = 0; c < 2; ++c )
|
||||
{
|
||||
size_t cell_idx = face2Cells[2 * i + c] + areaElemStartIndex[nArea];
|
||||
// Take just maximum
|
||||
if ( std::isnan( values[cell_idx] ) || values[cell_idx] < val )
|
||||
{
|
||||
values[cell_idx] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto dataset : datasets )
|
||||
{
|
||||
dataset->setStatistics( MDAL::calculateStatistics( dataset ) );
|
||||
group->datasets.push_back( dataset );
|
||||
}
|
||||
group->setStatistics( MDAL::calculateStatistics( group ) );
|
||||
mMesh->datasetGroups.push_back( group );
|
||||
}
|
||||
|
||||
void MDAL::DriverHec2D::readFaceResults( const HdfFile &hdfFile,
|
||||
const std::vector<size_t> &areaElemStartIndex,
|
||||
const std::vector<std::string> &flowAreaNames )
|
||||
{
|
||||
// UNSTEADY
|
||||
HdfGroup flowGroup = get2DFlowAreasGroup( hdfFile, "Unsteady Time Series" );
|
||||
std::vector<float> times = readTimes( hdfFile );
|
||||
|
||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Face Shear Stress", "Face Shear Stress", times );
|
||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Face Velocity", "Face Velocity", times );
|
||||
|
||||
// SUMMARY
|
||||
flowGroup = get2DFlowAreasGroup( hdfFile, "Summary Output" );
|
||||
times.clear();
|
||||
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 Velocity", "Face Velocity/Maximums", times );
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<MDAL::MemoryDataset> MDAL::DriverHec2D::readElemOutput( const HdfGroup &rootGroup,
|
||||
const std::vector<size_t> &areaElemStartIndex,
|
||||
const std::vector<std::string> &flowAreaNames,
|
||||
const std::string rawDatasetName,
|
||||
const std::string datasetName,
|
||||
const std::vector<float> ×,
|
||||
std::shared_ptr<MDAL::MemoryDataset> bed_elevation )
|
||||
{
|
||||
double eps = std::numeric_limits<double>::min();
|
||||
|
||||
std::shared_ptr<DatasetGroup> group = std::make_shared< DatasetGroup >(
|
||||
mMesh.get(),
|
||||
mFileName,
|
||||
datasetName
|
||||
);
|
||||
group->setIsOnVertices( false );
|
||||
group->setIsScalar( true );
|
||||
|
||||
std::vector<std::shared_ptr<MDAL::MemoryDataset>> datasets;
|
||||
|
||||
for ( size_t tidx = 0; tidx < times.size(); ++tidx )
|
||||
{
|
||||
std::shared_ptr<MDAL::MemoryDataset> dataset = std::make_shared< MemoryDataset >( group.get() );
|
||||
double time = static_cast<double>( times[tidx] );
|
||||
dataset->setTime( time );
|
||||
datasets.push_back( dataset );
|
||||
}
|
||||
|
||||
for ( size_t nArea = 0; nArea < flowAreaNames.size(); ++nArea )
|
||||
{
|
||||
size_t nAreaElements = areaElemStartIndex[nArea + 1] - areaElemStartIndex[nArea];
|
||||
std::string flowAreaName = flowAreaNames[nArea];
|
||||
HdfGroup gFlowAreaRes = openHdfGroup( rootGroup, flowAreaName );
|
||||
|
||||
HdfDataset dsVals = openHdfDataset( gFlowAreaRes, rawDatasetName );
|
||||
std::vector<float> vals = dsVals.readArray();
|
||||
|
||||
for ( size_t tidx = 0; tidx < times.size(); ++tidx )
|
||||
{
|
||||
std::shared_ptr<MDAL::MemoryDataset> dataset = datasets[tidx];
|
||||
double *values = dataset->values();
|
||||
|
||||
for ( size_t i = 0; i < nAreaElements; ++i )
|
||||
{
|
||||
size_t idx = tidx * nAreaElements + i;
|
||||
size_t eInx = areaElemStartIndex[nArea] + i;
|
||||
double val = static_cast<double>( vals[idx] );
|
||||
if ( !std::isnan( val ) )
|
||||
{
|
||||
if ( !bed_elevation )
|
||||
{
|
||||
// we are populating bed elevation dataset
|
||||
values[eInx] = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( datasetName == "Depth" )
|
||||
{
|
||||
if ( fabs( val ) > eps ) // 0 Depth is no-data
|
||||
{
|
||||
values[eInx] = val;
|
||||
}
|
||||
}
|
||||
else //Water surface
|
||||
{
|
||||
assert( bed_elevation );
|
||||
double bed_elev = bed_elevation->values()[eInx];
|
||||
if ( std::isnan( bed_elev ) || fabs( bed_elev - val ) > eps ) // change from bed elevation
|
||||
{
|
||||
values[eInx] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto dataset : datasets )
|
||||
{
|
||||
dataset->setStatistics( MDAL::calculateStatistics( dataset ) );
|
||||
group->datasets.push_back( dataset );
|
||||
}
|
||||
group->setStatistics( MDAL::calculateStatistics( group ) );
|
||||
mMesh->datasetGroups.push_back( group );
|
||||
|
||||
return datasets[0];
|
||||
}
|
||||
|
||||
std::shared_ptr<MDAL::MemoryDataset> MDAL::DriverHec2D::readBedElevation(
|
||||
const HdfGroup &gGeom2DFlowAreas,
|
||||
const std::vector<size_t> &areaElemStartIndex,
|
||||
const std::vector<std::string> &flowAreaNames )
|
||||
{
|
||||
std::vector<float> times( 1, 0.0f );
|
||||
return readElemOutput(
|
||||
gGeom2DFlowAreas,
|
||||
areaElemStartIndex,
|
||||
flowAreaNames,
|
||||
"Cells Minimum Elevation",
|
||||
"Bed Elevation",
|
||||
times,
|
||||
std::shared_ptr<MDAL::MemoryDataset>()
|
||||
);
|
||||
}
|
||||
|
||||
void MDAL::DriverHec2D::readElemResults(
|
||||
const HdfFile &hdfFile,
|
||||
std::shared_ptr<MDAL::MemoryDataset> bed_elevation,
|
||||
const std::vector<size_t> &areaElemStartIndex,
|
||||
const std::vector<std::string> &flowAreaNames )
|
||||
{
|
||||
// UNSTEADY
|
||||
HdfGroup flowGroup = get2DFlowAreasGroup( hdfFile, "Unsteady Time Series" );
|
||||
std::vector<float> times = readTimes( hdfFile );
|
||||
|
||||
readElemOutput(
|
||||
flowGroup,
|
||||
areaElemStartIndex,
|
||||
flowAreaNames,
|
||||
"Water Surface",
|
||||
"Water Surface",
|
||||
times,
|
||||
bed_elevation );
|
||||
readElemOutput(
|
||||
flowGroup,
|
||||
areaElemStartIndex,
|
||||
flowAreaNames,
|
||||
"Depth",
|
||||
"Depth",
|
||||
times,
|
||||
bed_elevation );
|
||||
|
||||
// SUMMARY
|
||||
flowGroup = get2DFlowAreasGroup( hdfFile, "Summary Output" );
|
||||
times.clear();
|
||||
times.push_back( 0.0f );
|
||||
|
||||
readElemOutput(
|
||||
flowGroup,
|
||||
areaElemStartIndex,
|
||||
flowAreaNames,
|
||||
"Maximum Water Surface",
|
||||
"Water Surface/Maximums",
|
||||
times,
|
||||
bed_elevation
|
||||
);
|
||||
}
|
||||
|
||||
std::vector<std::string> read2DFlowAreasNames( HdfGroup gGeom2DFlowAreas )
|
||||
{
|
||||
HdfDataset dsNames = openHdfDataset( gGeom2DFlowAreas, "Names" );
|
||||
std::vector<std::string> names = dsNames.readArrayString();
|
||||
if ( names.empty() )
|
||||
{
|
||||
throw MDAL_Status::Err_InvalidData;
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
void MDAL::DriverHec2D::setProjection( HdfFile hdfFile )
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string proj_wkt = openHdfAttribute( hdfFile, "Projection" );
|
||||
mMesh->setSourceCrsFromWKT( proj_wkt );
|
||||
}
|
||||
catch ( MDAL_Status ) { /* projection not set */}
|
||||
}
|
||||
|
||||
void MDAL::DriverHec2D::parseMesh(
|
||||
HdfGroup gGeom2DFlowAreas,
|
||||
std::vector<size_t> &areaElemStartIndex,
|
||||
const std::vector<std::string> &flowAreaNames )
|
||||
{
|
||||
Faces faces;
|
||||
Vertices vertices;
|
||||
|
||||
size_t maxVerticesInFace = 0;
|
||||
|
||||
for ( size_t nArea = 0; nArea < flowAreaNames.size(); ++nArea )
|
||||
{
|
||||
std::string flowAreaName = flowAreaNames[nArea];
|
||||
|
||||
HdfGroup gArea = openHdfGroup( gGeom2DFlowAreas, flowAreaName );
|
||||
|
||||
HdfDataset dsCoords = openHdfDataset( gArea, "FacePoints Coordinate" );
|
||||
std::vector<hsize_t> cdims = dsCoords.dims();
|
||||
std::vector<double> coords = dsCoords.readArrayDouble(); //2xnNodes matrix in array
|
||||
size_t nNodes = cdims[0];
|
||||
size_t areaNodeStartIndex = vertices.size();
|
||||
vertices.resize( areaNodeStartIndex + nNodes );
|
||||
for ( size_t n = 0; n < nNodes; ++n )
|
||||
{
|
||||
size_t nIdx = areaNodeStartIndex + n;
|
||||
vertices[nIdx].x = coords[cdims[1] * n];
|
||||
vertices[nIdx].y = coords[cdims[1] * n + 1];
|
||||
}
|
||||
|
||||
HdfDataset dsElems = openHdfDataset( gArea, "Cells FacePoint Indexes" );
|
||||
std::vector<hsize_t> edims = dsElems.dims();
|
||||
size_t nElems = edims[0];
|
||||
size_t maxFaces = edims[1]; // elems have up to 8 faces, but sometimes the table has less than 8 columns
|
||||
std::vector<int> elem_nodes = dsElems.readArrayInt(); //maxFacesxnElements matrix in array
|
||||
areaElemStartIndex[nArea] = faces.size();
|
||||
faces.resize( faces.size() + nElems );
|
||||
for ( size_t e = 0; e < nElems; ++e )
|
||||
{
|
||||
size_t eIdx = areaElemStartIndex[nArea] + e;
|
||||
std::vector<size_t> idx( maxFaces );
|
||||
size_t nValidVertexes = maxFaces;
|
||||
for ( size_t fi = 0; fi < maxFaces; ++fi )
|
||||
{
|
||||
int elem_node_idx = elem_nodes[edims[1] * e + fi];
|
||||
|
||||
if ( elem_node_idx == -1 )
|
||||
{
|
||||
nValidVertexes = fi;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
idx[fi] = areaNodeStartIndex + static_cast<size_t>( elem_node_idx ); // shift by this area start node index
|
||||
}
|
||||
}
|
||||
if ( nValidVertexes > 0 )
|
||||
faces[eIdx].assign( idx.begin(), std::next( idx.begin(), nValidVertexes ) );
|
||||
|
||||
if ( nValidVertexes > maxVerticesInFace )
|
||||
maxVerticesInFace = nValidVertexes;
|
||||
}
|
||||
}
|
||||
areaElemStartIndex[flowAreaNames.size()] = faces.size();
|
||||
|
||||
mMesh.reset(
|
||||
new MemoryMesh(
|
||||
vertices.size(),
|
||||
faces.size(),
|
||||
maxVerticesInFace,
|
||||
computeExtent( vertices ),
|
||||
mFileName
|
||||
)
|
||||
);
|
||||
mMesh->faces = faces;
|
||||
mMesh->vertices = vertices;
|
||||
}
|
||||
|
||||
MDAL::DriverHec2D::DriverHec2D()
|
||||
: Driver( "HEC2D",
|
||||
"HEC-RAS 2D",
|
||||
"*.hdf",
|
||||
DriverType::CanReadMeshAndDatasets )
|
||||
{
|
||||
}
|
||||
|
||||
MDAL::DriverHec2D *MDAL::DriverHec2D::create()
|
||||
{
|
||||
return new DriverHec2D();
|
||||
}
|
||||
|
||||
bool MDAL::DriverHec2D::canRead( const std::string &uri )
|
||||
{
|
||||
try
|
||||
{
|
||||
HdfFile hdfFile = openHdfFile( uri );
|
||||
std::string fileType = openHdfAttribute( hdfFile, "File Type" );
|
||||
if ( fileType != "HEC-RAS Results" )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch ( MDAL_Status )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<MDAL::Mesh> MDAL::DriverHec2D::load( const std::string &resultsFile, MDAL_Status *status )
|
||||
{
|
||||
mFileName = resultsFile;
|
||||
if ( status ) *status = MDAL_Status::None;
|
||||
mMesh.reset();
|
||||
|
||||
try
|
||||
{
|
||||
HdfFile hdfFile = openHdfFile( mFileName );
|
||||
|
||||
// Verify it is correct file
|
||||
std::string fileType = openHdfAttribute( hdfFile, "File Type" );
|
||||
if ( fileType != "HEC-RAS Results" )
|
||||
{
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
|
||||
HdfGroup gGeom = openHdfGroup( hdfFile, "Geometry" );
|
||||
HdfGroup gGeom2DFlowAreas = openHdfGroup( gGeom, "2D Flow Areas" );
|
||||
|
||||
std::vector<std::string> flowAreaNames = read2DFlowAreasNames( gGeom2DFlowAreas );
|
||||
std::vector<size_t> areaElemStartIndex( flowAreaNames.size() + 1 );
|
||||
|
||||
parseMesh( gGeom2DFlowAreas, areaElemStartIndex, flowAreaNames );
|
||||
setProjection( hdfFile );
|
||||
|
||||
//Elevation
|
||||
std::shared_ptr<MDAL::MemoryDataset> bed_elevation = readBedElevation( gGeom2DFlowAreas, areaElemStartIndex, flowAreaNames );
|
||||
|
||||
// Element centered Values
|
||||
readElemResults( hdfFile, bed_elevation, areaElemStartIndex, flowAreaNames );
|
||||
|
||||
// Face centered Values
|
||||
readFaceResults( hdfFile, areaElemStartIndex, flowAreaNames );
|
||||
}
|
||||
catch ( MDAL_Status error )
|
||||
{
|
||||
if ( status ) *status = ( error );
|
||||
mMesh.reset();
|
||||
}
|
||||
|
||||
return std::unique_ptr<Mesh>( mMesh.release() );
|
||||
}
|
67
external/mdal/frmts/mdal_hec2d.hpp
vendored
Normal file
67
external/mdal/frmts/mdal_hec2d.hpp
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
|
||||
*/
|
||||
|
||||
#ifndef MDAL_HEC2D_HPP
|
||||
#define MDAL_HEC2D_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "mdal_data_model.hpp"
|
||||
#include "mdal_memory_data_model.hpp"
|
||||
#include "mdal.h"
|
||||
#include "mdal_hdf5.hpp"
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
class DriverHec2D: public Driver
|
||||
{
|
||||
public:
|
||||
DriverHec2D();
|
||||
~DriverHec2D( ) override = default;
|
||||
DriverHec2D *create() override;
|
||||
|
||||
bool canRead( const std::string &uri ) override;
|
||||
std::unique_ptr< Mesh > load( const std::string &resultsFile, MDAL_Status *status ) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr< MDAL::MemoryMesh > mMesh;
|
||||
std::string mFileName;
|
||||
|
||||
void readFaceOutput( const HdfFile &hdfFile,
|
||||
const HdfGroup &rootGroup,
|
||||
const std::vector<size_t> &areaElemStartIndex,
|
||||
const std::vector<std::string> &flowAreaNames,
|
||||
const std::string rawDatasetName,
|
||||
const std::string datasetName,
|
||||
const std::vector<float> × );
|
||||
void readFaceResults( const HdfFile &hdfFile,
|
||||
const std::vector<size_t> &areaElemStartIndex,
|
||||
const std::vector<std::string> &flowAreaNames );
|
||||
std::shared_ptr<MDAL::MemoryDataset> readElemOutput(
|
||||
const HdfGroup &rootGroup,
|
||||
const std::vector<size_t> &areaElemStartIndex,
|
||||
const std::vector<std::string> &flowAreaNames,
|
||||
const std::string rawDatasetName,
|
||||
const std::string datasetName,
|
||||
const std::vector<float> ×,
|
||||
std::shared_ptr<MDAL::MemoryDataset> bed_elevation );
|
||||
std::shared_ptr<MDAL::MemoryDataset> readBedElevation(
|
||||
const HdfGroup &gGeom2DFlowAreas,
|
||||
const std::vector<size_t> &areaElemStartIndex,
|
||||
const std::vector<std::string> &flowAreaNames );
|
||||
void setProjection( HdfFile hdfFile );
|
||||
void parseMesh( HdfGroup gGeom2DFlowAreas,
|
||||
std::vector<size_t> &areaElemStartIndex,
|
||||
const std::vector<std::string> &flowAreaNames );
|
||||
void readElemResults(
|
||||
const HdfFile &hdfFile,
|
||||
std::shared_ptr<MDAL::MemoryDataset> bed_elevation,
|
||||
const std::vector<size_t> &areaElemStartIndex,
|
||||
const std::vector<std::string> &flowAreaNames );
|
||||
};
|
||||
|
||||
} // namespace MDAL
|
||||
#endif //MDAL_HEC2D_HPP
|
6
external/mdal/frmts/mdal_netcdf.hpp
vendored
6
external/mdal/frmts/mdal_netcdf.hpp
vendored
@ -27,16 +27,14 @@ class NetCDFFile
|
||||
return mNcid;
|
||||
}
|
||||
|
||||
int openFile( const std::string &fileName )
|
||||
void openFile( const std::string &fileName )
|
||||
{
|
||||
int ncid = 0;
|
||||
int res = nc_open( fileName.c_str(), NC_NOWRITE, &mNcid );
|
||||
if ( res != NC_NOERR )
|
||||
{
|
||||
//qDebug("error: %s", nc_strerror(res));
|
||||
MDAL::debug( nc_strerror( res ) );
|
||||
throw MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
return ncid;
|
||||
}
|
||||
|
||||
bool hasVariable( const std::string &name ) const
|
||||
|
373
external/mdal/frmts/mdal_sww.cpp
vendored
Normal file
373
external/mdal/frmts/mdal_sww.cpp
vendored
Normal file
@ -0,0 +1,373 @@
|
||||
/*
|
||||
MDAL - mMesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2016 Lutra Consulting
|
||||
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#include "mdal_netcdf.hpp"
|
||||
#include "mdal_sww.hpp"
|
||||
|
||||
// threshold for determining whether an element is active (wet)
|
||||
// the format does not explicitly store that information so we
|
||||
// determine that when loading data
|
||||
#define DEPTH_THRESHOLD 0.0001 // in meters
|
||||
|
||||
MDAL::DriverSWW::DriverSWW()
|
||||
: Driver( "SWW",
|
||||
"AnuGA",
|
||||
"*.sww",
|
||||
DriverType::CanReadMeshAndDatasets )
|
||||
{
|
||||
}
|
||||
|
||||
MDAL::DriverSWW *MDAL::DriverSWW::create()
|
||||
{
|
||||
return new DriverSWW();
|
||||
}
|
||||
|
||||
bool MDAL::DriverSWW::canRead( const std::string &uri )
|
||||
{
|
||||
int ncid;
|
||||
int res;
|
||||
|
||||
// open
|
||||
res = nc_open( uri.c_str(), NC_NOWRITE, &ncid );
|
||||
if ( res != NC_NOERR )
|
||||
{
|
||||
MDAL::debug( nc_strerror( res ) );
|
||||
nc_close( ncid );
|
||||
return false;
|
||||
}
|
||||
|
||||
// get dimensions
|
||||
int nVolumesId, nVerticesId, nPointsId, nTimestepsId;
|
||||
if ( nc_inq_dimid( ncid, "number_of_volumes", &nVolumesId ) != NC_NOERR ||
|
||||
nc_inq_dimid( ncid, "number_of_vertices", &nVerticesId ) != NC_NOERR ||
|
||||
nc_inq_dimid( ncid, "number_of_points", &nPointsId ) != NC_NOERR ||
|
||||
nc_inq_dimid( ncid, "number_of_timesteps", &nTimestepsId ) != NC_NOERR )
|
||||
{
|
||||
nc_close( ncid );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<MDAL::Mesh> MDAL::DriverSWW::load( const std::string &resultsFile,
|
||||
MDAL_Status *status )
|
||||
{
|
||||
mFileName = resultsFile;
|
||||
if ( status ) *status = MDAL_Status::None;
|
||||
|
||||
int ncid;
|
||||
int res;
|
||||
|
||||
res = nc_open( mFileName.c_str(), NC_NOWRITE, &ncid );
|
||||
if ( res != NC_NOERR )
|
||||
{
|
||||
MDAL::debug( nc_strerror( res ) );
|
||||
nc_close( ncid );
|
||||
if ( status ) *status = MDAL_Status::Err_UnknownFormat;
|
||||
return std::unique_ptr< MDAL::Mesh >();
|
||||
}
|
||||
|
||||
// get dimensions
|
||||
int nVolumesId, nVerticesId, nPointsId, nTimestepsId;
|
||||
size_t nVolumes, nVertices, nPoints, nTimesteps;
|
||||
if ( nc_inq_dimid( ncid, "number_of_volumes", &nVolumesId ) != NC_NOERR ||
|
||||
nc_inq_dimid( ncid, "number_of_vertices", &nVerticesId ) != NC_NOERR ||
|
||||
nc_inq_dimid( ncid, "number_of_points", &nPointsId ) != NC_NOERR ||
|
||||
nc_inq_dimid( ncid, "number_of_timesteps", &nTimestepsId ) != NC_NOERR )
|
||||
{
|
||||
nc_close( ncid );
|
||||
if ( status ) *status = MDAL_Status::Err_UnknownFormat;
|
||||
return std::unique_ptr< MDAL::Mesh >();
|
||||
}
|
||||
if ( nc_inq_dimlen( ncid, nVolumesId, &nVolumes ) != NC_NOERR ||
|
||||
nc_inq_dimlen( ncid, nVerticesId, &nVertices ) != NC_NOERR ||
|
||||
nc_inq_dimlen( ncid, nPointsId, &nPoints ) != NC_NOERR ||
|
||||
nc_inq_dimlen( ncid, nTimestepsId, &nTimesteps ) != NC_NOERR )
|
||||
{
|
||||
nc_close( ncid );
|
||||
if ( status ) *status = MDAL_Status::Err_UnknownFormat;
|
||||
return std::unique_ptr< MDAL::Mesh >();
|
||||
}
|
||||
|
||||
if ( nVertices != 3 )
|
||||
{
|
||||
MDAL::debug( "Expecting triangular elements!" );
|
||||
nc_close( ncid );
|
||||
if ( status ) *status = MDAL_Status::Err_UnknownFormat;
|
||||
return std::unique_ptr< MDAL::Mesh >();
|
||||
}
|
||||
|
||||
int xid, yid, zid, volumesid, timeid, stageid;
|
||||
if ( nc_inq_varid( ncid, "x", &xid ) != NC_NOERR ||
|
||||
nc_inq_varid( ncid, "y", &yid ) != NC_NOERR ||
|
||||
nc_inq_varid( ncid, "volumes", &volumesid ) != NC_NOERR ||
|
||||
nc_inq_varid( ncid, "time", &timeid ) != NC_NOERR ||
|
||||
nc_inq_varid( ncid, "stage", &stageid ) != NC_NOERR )
|
||||
{
|
||||
nc_close( ncid );
|
||||
if ( status ) *status = MDAL_Status::Err_UnknownFormat;
|
||||
return std::unique_ptr< MDAL::Mesh >();
|
||||
}
|
||||
|
||||
// load mesh data
|
||||
std::vector<float> px( nPoints ), py( nPoints ), pz( nPoints );
|
||||
std::vector<int> pvolumes( nVertices * nVolumes );
|
||||
if ( nc_get_var_float( ncid, xid, px.data() ) != NC_NOERR ||
|
||||
nc_get_var_float( ncid, yid, py.data() ) != NC_NOERR ||
|
||||
nc_get_var_int( ncid, volumesid, pvolumes.data() ) != NC_NOERR )
|
||||
{
|
||||
nc_close( ncid );
|
||||
if ( status ) *status = MDAL_Status::Err_UnknownFormat;
|
||||
return std::unique_ptr< MDAL::Mesh >();
|
||||
}
|
||||
|
||||
// we may need to apply a shift to the X,Y coordinates
|
||||
float xLLcorner = 0, yLLcorner = 0;
|
||||
nc_get_att_float( ncid, NC_GLOBAL, "xllcorner", &xLLcorner );
|
||||
nc_get_att_float( ncid, NC_GLOBAL, "yllcorner", &yLLcorner );
|
||||
|
||||
MDAL::Vertices nodes( nPoints );
|
||||
Vertex *nodesPtr = nodes.data();
|
||||
for ( size_t i = 0; i < nPoints; ++i, ++nodesPtr )
|
||||
{
|
||||
nodesPtr->x = static_cast<double>( px[i] + xLLcorner );
|
||||
nodesPtr->y = static_cast<double>( py[i] + yLLcorner );
|
||||
}
|
||||
|
||||
std::vector<float> times( nTimesteps );
|
||||
nc_get_var_float( ncid, timeid, times.data() );
|
||||
|
||||
int zDims = 0;
|
||||
if ( nc_inq_varid( ncid, "z", &zid ) == NC_NOERR &&
|
||||
nc_get_var_float( ncid, zid, pz.data() ) == NC_NOERR )
|
||||
{
|
||||
// older SWW format: elevation is constant over time
|
||||
|
||||
zDims = 1;
|
||||
}
|
||||
else if ( nc_inq_varid( ncid, "elevation", &zid ) == NC_NOERR &&
|
||||
nc_inq_varndims( ncid, zid, &zDims ) == NC_NOERR &&
|
||||
( ( zDims == 1 && nc_get_var_float( ncid, zid, pz.data() ) == NC_NOERR ) || zDims == 2 ) )
|
||||
{
|
||||
// we're good
|
||||
}
|
||||
else
|
||||
{
|
||||
// neither "z" nor "elevation" are present -> something is going wrong
|
||||
nc_close( ncid );
|
||||
if ( status ) *status = MDAL_Status::Err_UnknownFormat;
|
||||
return std::unique_ptr< MDAL::Mesh >();
|
||||
}
|
||||
|
||||
MDAL::Faces elements( nVolumes );
|
||||
for ( size_t i = 0; i < nVolumes; ++i )
|
||||
{
|
||||
elements[i].resize( 3 );
|
||||
elements[i][0] = static_cast<size_t>( pvolumes[3 * i + 0] );
|
||||
elements[i][1] = static_cast<size_t>( pvolumes[3 * i + 1] );
|
||||
elements[i][2] = static_cast<size_t>( pvolumes[3 * i + 2] );
|
||||
}
|
||||
std::unique_ptr< MDAL::MemoryMesh > mesh(
|
||||
new MemoryMesh(
|
||||
nodes.size(),
|
||||
elements.size(),
|
||||
3, // triangles
|
||||
computeExtent( nodes ),
|
||||
mFileName
|
||||
)
|
||||
);
|
||||
mesh->faces = elements;
|
||||
mesh->vertices = nodes;
|
||||
|
||||
// Create a dataset for the bed elevation
|
||||
std::shared_ptr<MDAL::DatasetGroup> bedDs = std::make_shared<MDAL::DatasetGroup> (
|
||||
mesh.get(),
|
||||
mFileName,
|
||||
"Bed Elevation" );
|
||||
bedDs->setIsOnVertices( true );
|
||||
bedDs->setIsScalar( true );
|
||||
|
||||
// read bed elevations
|
||||
std::vector<std::shared_ptr<MDAL::MemoryDataset>> elevationOutputs;
|
||||
if ( zDims == 1 )
|
||||
{
|
||||
// either "z" or "elevation" with 1 dimension
|
||||
std::shared_ptr<MDAL::MemoryDataset> o = std::make_shared<MDAL::MemoryDataset>( bedDs.get() );
|
||||
o->setTime( 0.0 );
|
||||
double *values = o->values();
|
||||
for ( size_t i = 0; i < nPoints; ++i )
|
||||
{
|
||||
double z = static_cast<double>( pz[i] );
|
||||
values[i] = z;
|
||||
mesh->vertices[i].z = z;
|
||||
}
|
||||
o->setStatistics( MDAL::calculateStatistics( o ) );
|
||||
bedDs->datasets.push_back( o );
|
||||
elevationOutputs.push_back( o );
|
||||
}
|
||||
else if ( zDims == 2 )
|
||||
{
|
||||
// newer SWW format: elevation may change over time
|
||||
for ( size_t t = 0; t < nTimesteps; ++t )
|
||||
{
|
||||
std::shared_ptr<MDAL::MemoryDataset> toe = std::make_shared<MDAL::MemoryDataset>( bedDs.get() );
|
||||
toe->setTime( static_cast<double>( times[t] ) / 3600. );
|
||||
double *elev = toe->values();
|
||||
|
||||
// fetching "elevation" data for one timestep
|
||||
size_t start[2], count[2];
|
||||
const ptrdiff_t stride[2] = {1, 1};
|
||||
start[0] = t;
|
||||
start[1] = 0;
|
||||
count[0] = 1;
|
||||
count[1] = nPoints;
|
||||
std::vector<float> buffer( nPoints );
|
||||
nc_get_vars_float( ncid, zid, start, count, stride, buffer.data() );
|
||||
for ( size_t i = 0; i < nPoints; ++i )
|
||||
{
|
||||
double val = static_cast<double>( buffer[i] );
|
||||
elev[i] = val;
|
||||
}
|
||||
|
||||
toe->setStatistics( MDAL::calculateStatistics( toe ) );
|
||||
bedDs->datasets.push_back( toe );
|
||||
elevationOutputs.push_back( toe );
|
||||
}
|
||||
}
|
||||
|
||||
bedDs->setStatistics( MDAL::calculateStatistics( bedDs ) );
|
||||
mesh->datasetGroups.push_back( bedDs );
|
||||
|
||||
// load results
|
||||
std::shared_ptr<MDAL::DatasetGroup> dss = std::make_shared<MDAL::DatasetGroup> (
|
||||
mesh.get(),
|
||||
mFileName,
|
||||
"Stage" );
|
||||
dss->setIsOnVertices( true );
|
||||
dss->setIsScalar( true );
|
||||
|
||||
std::shared_ptr<MDAL::DatasetGroup> dsd = std::make_shared<MDAL::DatasetGroup> (
|
||||
mesh.get(),
|
||||
mFileName,
|
||||
"Depth" );
|
||||
dsd->setIsOnVertices( true );
|
||||
dsd->setIsScalar( true );
|
||||
|
||||
for ( size_t t = 0; t < nTimesteps; ++t )
|
||||
{
|
||||
const std::shared_ptr<MDAL::MemoryDataset> elevO = elevationOutputs.size() > 1 ? elevationOutputs[t] : elevationOutputs[0];
|
||||
const double *elev = elevO->constValues();
|
||||
|
||||
std::shared_ptr<MDAL::MemoryDataset> tos = std::make_shared<MDAL::MemoryDataset>( dss.get() );
|
||||
tos->setTime( static_cast<double>( times[t] ) / 3600. );
|
||||
double *values = tos->values();
|
||||
|
||||
// fetching "stage" data for one timestep
|
||||
size_t start[2], count[2];
|
||||
const ptrdiff_t stride[2] = {1, 1};
|
||||
start[0] = t;
|
||||
start[1] = 0;
|
||||
count[0] = 1;
|
||||
count[1] = nPoints;
|
||||
std::vector<float> buffer( nPoints );
|
||||
nc_get_vars_float( ncid, stageid, start, count, stride, buffer.data() );
|
||||
for ( size_t i = 0; i < nPoints; ++i )
|
||||
{
|
||||
double val = static_cast<double>( buffer[i] );
|
||||
values[i] = val;
|
||||
}
|
||||
|
||||
// derived data: depth = stage - elevation
|
||||
std::shared_ptr<MDAL::MemoryDataset> tod = std::make_shared<MDAL::MemoryDataset>( dsd.get() );
|
||||
tod->setTime( tos->time() );
|
||||
double *depths = tod->values();
|
||||
int *activeTos = tos->active();
|
||||
int *activeTod = tod->active();
|
||||
|
||||
for ( size_t j = 0; j < nPoints; ++j )
|
||||
depths[j] = values[j] - elev[j];
|
||||
|
||||
// determine which elements are active (wet)
|
||||
for ( size_t elemidx = 0; elemidx < nVolumes; ++elemidx )
|
||||
{
|
||||
const Face &elem = mesh->faces[elemidx];
|
||||
double v0 = depths[elem[0]];
|
||||
double v1 = depths[elem[1]];
|
||||
double v2 = depths[elem[2]];
|
||||
activeTos[elemidx] = v0 > DEPTH_THRESHOLD && v1 > DEPTH_THRESHOLD && v2 > DEPTH_THRESHOLD;
|
||||
activeTod[elemidx] = activeTos[elemidx];
|
||||
}
|
||||
|
||||
tos->setStatistics( MDAL::calculateStatistics( tos ) );
|
||||
dss->datasets.push_back( tos );
|
||||
|
||||
tod->setStatistics( MDAL::calculateStatistics( tod ) );
|
||||
dsd->datasets.push_back( tod );
|
||||
}
|
||||
|
||||
dss->setStatistics( MDAL::calculateStatistics( dss ) );
|
||||
mesh->datasetGroups.push_back( dss );
|
||||
|
||||
dsd->setStatistics( MDAL::calculateStatistics( dsd ) );
|
||||
mesh->datasetGroups.push_back( dsd );
|
||||
|
||||
|
||||
int momentumxid, momentumyid;
|
||||
if ( nc_inq_varid( ncid, "xmomentum", &momentumxid ) == NC_NOERR &&
|
||||
nc_inq_varid( ncid, "ymomentum", &momentumyid ) == NC_NOERR )
|
||||
{
|
||||
std::shared_ptr<MDAL::DatasetGroup> mds = std::make_shared<MDAL::DatasetGroup> (
|
||||
mesh.get(),
|
||||
mFileName,
|
||||
"Momentum" );
|
||||
mds->setIsOnVertices( true );
|
||||
mds->setIsScalar( false );
|
||||
|
||||
std::vector<float> valuesX( nPoints ), valuesY( nPoints );
|
||||
for ( size_t t = 0; t < nTimesteps; ++t )
|
||||
{
|
||||
std::shared_ptr<MDAL::MemoryDataset> mto = std::make_shared<MDAL::MemoryDataset>( mds.get() );
|
||||
mto->setTime( static_cast<double>( times[t] ) / 3600. );
|
||||
double *values = mto->values();
|
||||
|
||||
std::shared_ptr<MDAL::MemoryDataset> mto0 = std::static_pointer_cast<MDAL::MemoryDataset>( dsd->datasets[t] );
|
||||
memcpy( mto->active(), mto0->active(), mesh->facesCount() * sizeof( int ) );
|
||||
|
||||
// fetching "stage" data for one timestep
|
||||
size_t start[2], count[2];
|
||||
const ptrdiff_t stride[2] = {1, 1};
|
||||
start[0] = t;
|
||||
start[1] = 0;
|
||||
count[0] = 1;
|
||||
count[1] = nPoints;
|
||||
nc_get_vars_float( ncid, momentumxid, start, count, stride, valuesX.data() );
|
||||
nc_get_vars_float( ncid, momentumyid, start, count, stride, valuesY.data() );
|
||||
|
||||
for ( size_t i = 0; i < nPoints; ++i )
|
||||
{
|
||||
values[2 * i] = static_cast<double>( valuesX[i] );
|
||||
values[2 * i + 1] = static_cast<double>( valuesY[i] );
|
||||
}
|
||||
|
||||
mto->setStatistics( MDAL::calculateStatistics( mto ) );
|
||||
mds->datasets.push_back( mto );
|
||||
}
|
||||
|
||||
|
||||
mds->setStatistics( MDAL::calculateStatistics( mds ) );
|
||||
mesh->datasetGroups.push_back( mds );
|
||||
}
|
||||
|
||||
nc_close( ncid );
|
||||
|
||||
return std::unique_ptr<Mesh>( mesh.release() );
|
||||
}
|
32
external/mdal/frmts/mdal_sww.hpp
vendored
Normal file
32
external/mdal/frmts/mdal_sww.hpp
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
|
||||
*/
|
||||
|
||||
#ifndef MDAL_SWW_HPP
|
||||
#define MDAL_SWW_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "mdal_data_model.hpp"
|
||||
#include "mdal_memory_data_model.hpp"
|
||||
#include "mdal.h"
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
// AnuGA format with extension .SWW
|
||||
class DriverSWW: public Driver
|
||||
{
|
||||
public:
|
||||
DriverSWW();
|
||||
~DriverSWW( ) override = default;
|
||||
DriverSWW *create() override;
|
||||
|
||||
std::unique_ptr< Mesh > load( const std::string &resultsFile, MDAL_Status *status ) override;
|
||||
bool canRead( const std::string &uri ) override;
|
||||
private:
|
||||
std::string mFileName;
|
||||
};
|
||||
} // namespace MDAL
|
||||
#endif //MDAL_SWW_HPP
|
42
external/mdal/frmts/mdal_xmdf.cpp
vendored
42
external/mdal/frmts/mdal_xmdf.cpp
vendored
@ -85,12 +85,39 @@ size_t MDAL::XmdfDataset::activeData( size_t indexStart, size_t count, int *buff
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MDAL::LoaderXmdf::LoaderXmdf( const std::string &datFile )
|
||||
: mDatFile( datFile )
|
||||
{}
|
||||
|
||||
void MDAL::LoaderXmdf::load( MDAL::Mesh *mesh, MDAL_Status *status )
|
||||
MDAL::DriverXmdf::DriverXmdf()
|
||||
: Driver( "XMDF",
|
||||
"TUFLOW XMDF",
|
||||
"*.xmdf",
|
||||
DriverType::CanReadOnlyDatasets )
|
||||
{
|
||||
}
|
||||
|
||||
MDAL::DriverXmdf *MDAL::DriverXmdf::create()
|
||||
{
|
||||
return new DriverXmdf();
|
||||
}
|
||||
|
||||
bool MDAL::DriverXmdf::canRead( const std::string &uri )
|
||||
{
|
||||
HdfFile file( uri );
|
||||
if ( !file.isValid() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HdfDataset dsFileType = file.dataset( "/File Type" );
|
||||
if ( dsFileType.readString() != "Xmdf" )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MDAL::DriverXmdf::load( const std::string &datFile, MDAL::Mesh *mesh, MDAL_Status *status )
|
||||
{
|
||||
mDatFile = datFile;
|
||||
mMesh = mesh;
|
||||
if ( status ) *status = MDAL_Status::None;
|
||||
|
||||
@ -168,7 +195,7 @@ void MDAL::LoaderXmdf::load( MDAL::Mesh *mesh, MDAL_Status *status )
|
||||
);
|
||||
}
|
||||
|
||||
void MDAL::LoaderXmdf::addDatasetGroupsFromXmdfGroup( DatasetGroups &groups, const HdfGroup &rootGroup, size_t vertexCount, size_t faceCount )
|
||||
void MDAL::DriverXmdf::addDatasetGroupsFromXmdfGroup( DatasetGroups &groups, const HdfGroup &rootGroup, size_t vertexCount, size_t faceCount )
|
||||
{
|
||||
for ( const std::string &name : rootGroup.groups() )
|
||||
{
|
||||
@ -179,7 +206,8 @@ void MDAL::LoaderXmdf::addDatasetGroupsFromXmdfGroup( DatasetGroups &groups, con
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<MDAL::DatasetGroup> MDAL::LoaderXmdf::readXmdfGroupAsDatasetGroup(
|
||||
|
||||
std::shared_ptr<MDAL::DatasetGroup> MDAL::DriverXmdf::readXmdfGroupAsDatasetGroup(
|
||||
const HdfGroup &rootGroup, const std::string &name, size_t vertexCount, size_t faceCount )
|
||||
{
|
||||
std::shared_ptr<DatasetGroup> group;
|
||||
|
11
external/mdal/frmts/mdal_xmdf.hpp
vendored
11
external/mdal/frmts/mdal_xmdf.hpp
vendored
@ -16,6 +16,7 @@
|
||||
#include "mdal_data_model.hpp"
|
||||
#include "mdal.h"
|
||||
#include "mdal_hdf5.hpp"
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
@ -54,11 +55,15 @@ namespace MDAL
|
||||
hsize_t mTimeIndex;
|
||||
};
|
||||
|
||||
class LoaderXmdf
|
||||
class DriverXmdf: public Driver
|
||||
{
|
||||
public:
|
||||
LoaderXmdf( const std::string &datFile );
|
||||
void load( Mesh *mesh, MDAL_Status *status );
|
||||
DriverXmdf();
|
||||
~DriverXmdf( ) override = default;
|
||||
DriverXmdf *create() override;
|
||||
|
||||
bool canRead( const std::string &uri ) override;
|
||||
void load( const std::string &datFile, Mesh *mesh, MDAL_Status *status ) override;
|
||||
|
||||
private:
|
||||
MDAL::Mesh *mMesh = nullptr;
|
||||
|
80
external/mdal/mdal.cpp
vendored
80
external/mdal/mdal.cpp
vendored
@ -7,9 +7,10 @@
|
||||
#include <stddef.h>
|
||||
#include <limits>
|
||||
#include <assert.h>
|
||||
#include <memory>
|
||||
|
||||
#include "mdal.h"
|
||||
#include "mdal_loader.hpp"
|
||||
#include "mdal_driver_manager.hpp"
|
||||
#include "mdal_data_model.hpp"
|
||||
|
||||
#define NODATA std::numeric_limits<double>::quiet_NaN()
|
||||
@ -20,7 +21,7 @@ static MDAL_Status sLastStatus;
|
||||
|
||||
const char *MDAL_Version()
|
||||
{
|
||||
return "0.1.1";
|
||||
return "0.1.2";
|
||||
}
|
||||
|
||||
MDAL_Status MDAL_LastStatus()
|
||||
@ -37,6 +38,77 @@ const char *_return_str( const std::string &str )
|
||||
return lastStr.c_str();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
/// DRIVERS
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int MDAL_driverCount()
|
||||
{
|
||||
size_t count = MDAL::DriverManager::instance().driversCount();
|
||||
return static_cast<int>( count );
|
||||
}
|
||||
|
||||
DriverH MDAL_driverFromIndex( int index )
|
||||
{
|
||||
size_t idx = static_cast<size_t>( index );
|
||||
std::shared_ptr<MDAL::Driver> driver = MDAL::DriverManager::instance().driver( idx );
|
||||
return static_cast<DriverH>( driver.get() );
|
||||
}
|
||||
|
||||
DriverH MDAL_driverFromName( const char *name )
|
||||
{
|
||||
std::string nm = name;
|
||||
std::shared_ptr<MDAL::Driver> driver = MDAL::DriverManager::instance().driver( nm );
|
||||
return static_cast<DriverH>( driver.get() );
|
||||
}
|
||||
|
||||
bool MDAL_DR_meshLoadCapability( DriverH driver )
|
||||
{
|
||||
if ( !driver )
|
||||
{
|
||||
sLastStatus = MDAL_Status::Err_MissingDriver;
|
||||
return false;
|
||||
}
|
||||
|
||||
MDAL::Driver *d = static_cast< MDAL::Driver * >( driver );
|
||||
return d->type() == MDAL::DriverType::CanReadMeshAndDatasets;
|
||||
}
|
||||
|
||||
const char *MDAL_DR_longName( DriverH driver )
|
||||
{
|
||||
if ( !driver )
|
||||
{
|
||||
sLastStatus = MDAL_Status::Err_MissingDriver;
|
||||
return EMPTY_STR;
|
||||
}
|
||||
|
||||
MDAL::Driver *d = static_cast< MDAL::Driver * >( driver );
|
||||
return _return_str( d->longName() );
|
||||
}
|
||||
|
||||
const char *MDAL_DR_name( DriverH driver )
|
||||
{
|
||||
if ( !driver )
|
||||
{
|
||||
sLastStatus = MDAL_Status::Err_MissingDriver;
|
||||
return EMPTY_STR;
|
||||
}
|
||||
|
||||
MDAL::Driver *d = static_cast< MDAL::Driver * >( driver );
|
||||
return _return_str( d->name() );
|
||||
}
|
||||
|
||||
const char *MDAL_DR_filters( DriverH driver )
|
||||
{
|
||||
if ( !driver )
|
||||
{
|
||||
sLastStatus = MDAL_Status::Err_MissingDriver;
|
||||
return EMPTY_STR;
|
||||
}
|
||||
MDAL::Driver *d = static_cast< MDAL::Driver * >( driver );
|
||||
return _return_str( d->filters() );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
/// MESH
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -50,7 +122,7 @@ MeshH MDAL_LoadMesh( const char *meshFile )
|
||||
}
|
||||
|
||||
std::string filename( meshFile );
|
||||
return static_cast< MeshH >( MDAL::Loader::load( filename, &sLastStatus ).release() );
|
||||
return static_cast< MeshH >( MDAL::DriverManager::instance().load( filename, &sLastStatus ).release() );
|
||||
}
|
||||
|
||||
|
||||
@ -150,7 +222,7 @@ void MDAL_M_LoadDatasets( MeshH mesh, const char *datasetFile )
|
||||
MDAL::Mesh *m = static_cast< MDAL::Mesh * >( mesh );
|
||||
|
||||
std::string filename( datasetFile );
|
||||
MDAL::Loader::loadDatasets( m, datasetFile, &sLastStatus );
|
||||
MDAL::DriverManager::instance().loadDatasets( m, datasetFile, &sLastStatus );
|
||||
}
|
||||
|
||||
int MDAL_M_datasetGroupCount( MeshH mesh )
|
||||
|
142
external/mdal/mdal_driver_manager.cpp
vendored
Normal file
142
external/mdal/mdal_driver_manager.cpp
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
|
||||
*/
|
||||
|
||||
#include "mdal_config.hpp"
|
||||
#include "mdal_driver_manager.hpp"
|
||||
#include "frmts/mdal_2dm.hpp"
|
||||
#include "frmts/mdal_ascii_dat.hpp"
|
||||
#include "frmts/mdal_binary_dat.hpp"
|
||||
#include "mdal_utils.hpp"
|
||||
|
||||
#ifdef HAVE_HDF5
|
||||
#include "frmts/mdal_xmdf.hpp"
|
||||
#include "frmts/mdal_flo2d.hpp"
|
||||
#include "frmts/mdal_hec2d.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GDAL
|
||||
#include "frmts/mdal_gdal_grib.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETCDF
|
||||
#include "frmts/mdal_3di.hpp"
|
||||
#include "frmts/mdal_sww.hpp"
|
||||
#endif
|
||||
|
||||
#if defined HAVE_GDAL && defined HAVE_NETCDF
|
||||
#include "frmts/mdal_gdal_netcdf.hpp"
|
||||
#endif
|
||||
|
||||
std::unique_ptr<MDAL::Mesh> MDAL::DriverManager::load( const std::string &meshFile, MDAL_Status *status ) const
|
||||
{
|
||||
std::unique_ptr<MDAL::Mesh> mesh;
|
||||
|
||||
if ( !MDAL::fileExists( meshFile ) )
|
||||
{
|
||||
if ( status ) *status = MDAL_Status::Err_FileNotFound;
|
||||
return std::unique_ptr<MDAL::Mesh>();
|
||||
}
|
||||
|
||||
for ( const auto &driver : mDrivers )
|
||||
{
|
||||
if ( ( driver->type() == DriverType::CanReadMeshAndDatasets ) &&
|
||||
driver->canRead( meshFile ) )
|
||||
{
|
||||
std::unique_ptr<Driver> drv( driver->create() );
|
||||
mesh = drv->load( meshFile, status );
|
||||
if ( mesh ) // stop if he have the mesh
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( status && !mesh )
|
||||
*status = MDAL_Status::Err_UnknownFormat;
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
void MDAL::DriverManager::loadDatasets( Mesh *mesh, const std::string &datasetFile, MDAL_Status *status ) const
|
||||
{
|
||||
if ( !MDAL::fileExists( datasetFile ) )
|
||||
{
|
||||
if ( status ) *status = MDAL_Status::Err_FileNotFound;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !mesh )
|
||||
{
|
||||
if ( status ) *status = MDAL_Status::Err_IncompatibleMesh;
|
||||
return;
|
||||
}
|
||||
|
||||
for ( const auto &driver : mDrivers )
|
||||
{
|
||||
if ( ( driver->type() == DriverType::CanReadOnlyDatasets ) &&
|
||||
driver->canRead( datasetFile ) )
|
||||
{
|
||||
std::unique_ptr<Driver> drv( driver->create() );
|
||||
drv->load( datasetFile, mesh, status );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( status )
|
||||
*status = MDAL_Status::Err_UnknownFormat;
|
||||
}
|
||||
|
||||
size_t MDAL::DriverManager::driversCount() const
|
||||
{
|
||||
return mDrivers.size();
|
||||
}
|
||||
|
||||
std::shared_ptr<MDAL::Driver> MDAL::DriverManager::driver( size_t index ) const
|
||||
{
|
||||
if ( mDrivers.size() < index )
|
||||
{
|
||||
return std::shared_ptr<MDAL::Driver>();
|
||||
}
|
||||
else
|
||||
{
|
||||
return mDrivers[index];
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<MDAL::Driver> MDAL::DriverManager::driver( const std::string &driverName ) const
|
||||
{
|
||||
for ( const auto &dr : mDrivers )
|
||||
{
|
||||
if ( dr->name() == driverName )
|
||||
return dr;
|
||||
}
|
||||
return std::shared_ptr<MDAL::Driver>();
|
||||
}
|
||||
|
||||
MDAL::DriverManager::DriverManager()
|
||||
{
|
||||
// MESH DRIVERS
|
||||
mDrivers.push_back( std::make_shared<MDAL::Driver2dm>() );
|
||||
|
||||
#ifdef HAVE_HDF5
|
||||
mDrivers.push_back( std::make_shared<MDAL::DriverFlo2D>() );
|
||||
mDrivers.push_back( std::make_shared<MDAL::DriverHec2D>() );
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETCDF
|
||||
mDrivers.push_back( std::make_shared<MDAL::Driver3Di>() );
|
||||
mDrivers.push_back( std::make_shared<MDAL::DriverSWW>() );
|
||||
mDrivers.push_back( std::make_shared<MDAL::DriverGdalNetCDF>() );
|
||||
#endif
|
||||
|
||||
#if defined HAVE_GDAL && defined HAVE_NETCDF
|
||||
mDrivers.push_back( std::make_shared<MDAL::DriverGdalGrib>() );
|
||||
#endif // HAVE_GDAL && HAVE_NETCDF
|
||||
|
||||
// DATASET DRIVERS
|
||||
mDrivers.push_back( std::make_shared<MDAL::DriverAsciiDat>() );
|
||||
mDrivers.push_back( std::make_shared<MDAL::DriverBinaryDat>() );
|
||||
#ifdef HAVE_HDF5
|
||||
mDrivers.push_back( std::make_shared<MDAL::DriverXmdf>() );
|
||||
#endif
|
||||
}
|
46
external/mdal/mdal_driver_manager.hpp
vendored
Normal file
46
external/mdal/mdal_driver_manager.hpp
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
|
||||
*/
|
||||
|
||||
#ifndef MDAL_DRIVER_MANAGER_HPP
|
||||
#define MDAL_DRIVER_MANAGER_HPP
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "mdal.h"
|
||||
#include "mdal_data_model.hpp"
|
||||
#include "frmts/mdal_driver.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
|
||||
class DriverManager
|
||||
{
|
||||
public:
|
||||
static DriverManager &instance()
|
||||
{
|
||||
static DriverManager sInstance;
|
||||
return sInstance;
|
||||
}
|
||||
DriverManager( DriverManager const & ) = delete;
|
||||
void operator=( DriverManager const & ) = delete;
|
||||
|
||||
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;
|
||||
|
||||
size_t driversCount() const;
|
||||
std::shared_ptr<MDAL::Driver> driver( const std::string &driverName ) const;
|
||||
std::shared_ptr<MDAL::Driver> driver( size_t index ) const;
|
||||
|
||||
private:
|
||||
DriverManager();
|
||||
|
||||
std::vector<std::shared_ptr<MDAL::Driver>> mDrivers;
|
||||
};
|
||||
|
||||
} // namespace MDAL
|
||||
#endif //MDAL_DRIVER_MANAGER_HPP
|
88
external/mdal/mdal_loader.cpp
vendored
88
external/mdal/mdal_loader.cpp
vendored
@ -1,88 +0,0 @@
|
||||
/*
|
||||
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
|
||||
*/
|
||||
|
||||
#include "mdal_config.hpp"
|
||||
#include "mdal_loader.hpp"
|
||||
#include "frmts/mdal_2dm.hpp"
|
||||
#include "frmts/mdal_ascii_dat.hpp"
|
||||
#include "frmts/mdal_binary_dat.hpp"
|
||||
#include "mdal_utils.hpp"
|
||||
|
||||
#ifdef HAVE_HDF5
|
||||
#include "frmts/mdal_xmdf.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GDAL
|
||||
#include "frmts/mdal_gdal_grib.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETCDF
|
||||
#include "frmts/mdal_3di.hpp"
|
||||
#endif
|
||||
|
||||
#if defined HAVE_GDAL && defined HAVE_NETCDF
|
||||
#include "frmts/mdal_gdal_netcdf.hpp"
|
||||
#endif
|
||||
|
||||
std::unique_ptr<MDAL::Mesh> MDAL::Loader::load( const std::string &meshFile, MDAL_Status *status )
|
||||
{
|
||||
if ( !MDAL::fileExists( meshFile ) )
|
||||
{
|
||||
if ( status ) *status = MDAL_Status::Err_FileNotFound;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MDAL::Loader2dm loader2dm( meshFile );
|
||||
std::unique_ptr<MDAL::Mesh> mesh = loader2dm.load( status );
|
||||
|
||||
#ifdef HAVE_NETCDF
|
||||
if ( !mesh && status && *status == MDAL_Status::Err_UnknownFormat )
|
||||
{
|
||||
MDAL::Loader3Di loader3di( meshFile );
|
||||
mesh = loader3di.load( status );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GDAL
|
||||
if ( !mesh && status && *status == MDAL_Status::Err_UnknownFormat )
|
||||
{
|
||||
#ifdef HAVE_NETCDF
|
||||
if ( MDAL::endsWith( meshFile, ".nc" ) )
|
||||
{
|
||||
MDAL::LoaderGdalNetCDF loaderNetCDF( meshFile );
|
||||
mesh = loaderNetCDF.load( status );
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif // HAVE_GDAL && HAVE_NETCDF
|
||||
MDAL::LoaderGdalGrib loaderGrib( meshFile );
|
||||
mesh = loaderGrib.load( status );
|
||||
}
|
||||
#ifdef HAVE_NETCDF
|
||||
}
|
||||
#endif // HAVE_GDAL && HAVE_NETCDF
|
||||
#endif // HAVE_GDAL
|
||||
return mesh;
|
||||
}
|
||||
|
||||
void MDAL::Loader::loadDatasets( Mesh *mesh, const std::string &datasetFile, MDAL_Status *status )
|
||||
{
|
||||
MDAL::LoaderAsciiDat loaderAsciiDat( datasetFile );
|
||||
loaderAsciiDat.load( mesh, status );
|
||||
|
||||
if ( status && *status == MDAL_Status::Err_UnknownFormat )
|
||||
{
|
||||
MDAL::LoaderBinaryDat loaderBinaryDat( datasetFile );
|
||||
loaderBinaryDat.load( mesh, status );
|
||||
}
|
||||
|
||||
#ifdef HAVE_HDF5
|
||||
if ( status && *status == MDAL_Status::Err_UnknownFormat )
|
||||
{
|
||||
MDAL::LoaderXmdf loaderXmdf( datasetFile );
|
||||
loaderXmdf.load( mesh, status );
|
||||
}
|
||||
#endif
|
||||
}
|
27
external/mdal/mdal_loader.hpp
vendored
27
external/mdal/mdal_loader.hpp
vendored
@ -1,27 +0,0 @@
|
||||
/*
|
||||
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
|
||||
*/
|
||||
|
||||
#ifndef MDAL_LOADER_HPP
|
||||
#define MDAL_LOADER_HPP
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "mdal.h"
|
||||
#include "mdal_data_model.hpp"
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
|
||||
class Loader
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr< Mesh > load( const std::string &meshFile, MDAL_Status *status );
|
||||
static void loadDatasets( Mesh *mesh, const std::string &datasetFile, MDAL_Status *status );
|
||||
};
|
||||
|
||||
} // namespace MDAL
|
||||
#endif //MDAL_LOADER_HPP
|
2
external/mdal/mdal_memory_data_model.cpp
vendored
2
external/mdal/mdal_memory_data_model.cpp
vendored
@ -57,7 +57,7 @@ size_t MDAL::MemoryDataset::activeData( size_t indexStart, size_t count, int *bu
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( buffer, true, count * sizeof( int ) );
|
||||
memset( buffer, 1, count * sizeof( int ) );
|
||||
}
|
||||
|
||||
return count;
|
||||
|
1
external/mdal/mdal_memory_data_model.hpp
vendored
1
external/mdal/mdal_memory_data_model.hpp
vendored
@ -21,6 +21,7 @@ namespace MDAL
|
||||
double x;
|
||||
double y;
|
||||
double z; // Bed elevation
|
||||
|
||||
} Vertex;
|
||||
|
||||
typedef std::vector<size_t> Face;
|
||||
|
34
external/mdal/mdal_utils.cpp
vendored
34
external/mdal/mdal_utils.cpp
vendored
@ -12,6 +12,8 @@
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
bool MDAL::fileExists( const std::string &filename )
|
||||
{
|
||||
@ -73,6 +75,17 @@ double MDAL::toDouble( const std::string &str )
|
||||
return atof( str.c_str() );
|
||||
}
|
||||
|
||||
bool MDAL::isNumber( const std::string &str )
|
||||
{
|
||||
// https://stackoverflow.com/a/16465826/2838364
|
||||
return ( strspn( str.c_str(), "-.0123456789" ) == str.size() );
|
||||
}
|
||||
|
||||
int MDAL::toInt( const std::string &str )
|
||||
{
|
||||
return atoi( str.c_str() );
|
||||
}
|
||||
|
||||
std::string MDAL::baseName( const std::string &filename )
|
||||
{
|
||||
// https://stackoverflow.com/a/8520815/2838364
|
||||
@ -95,6 +108,27 @@ std::string MDAL::baseName( const std::string &filename )
|
||||
return fname;
|
||||
}
|
||||
|
||||
std::string MDAL::pathJoin( const std::string &path1, const std::string &path2 )
|
||||
{
|
||||
//https://stackoverflow.com/questions/6297738/how-to-build-a-full-path-string-safely-from-separate-strings#6297807
|
||||
#ifdef _MSC_VER
|
||||
return path1 + "\\" + path2;
|
||||
#else
|
||||
return path1 + "/" + path2;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string MDAL::dirName( const std::string &filename )
|
||||
{
|
||||
std::string dname( filename );
|
||||
const size_t last_slash_idx = dname.find_last_of( "\\/" );
|
||||
if ( std::string::npos != last_slash_idx )
|
||||
{
|
||||
dname.erase( last_slash_idx, dname.size() - last_slash_idx );
|
||||
}
|
||||
return dname;
|
||||
}
|
||||
|
||||
bool MDAL::contains( const std::string &str, const std::string &substr, ContainsBehaviour behaviour )
|
||||
{
|
||||
if ( behaviour == ContainsBehaviour::CaseSensitive )
|
||||
|
4
external/mdal/mdal_utils.hpp
vendored
4
external/mdal/mdal_utils.hpp
vendored
@ -32,6 +32,8 @@ namespace MDAL
|
||||
/** Return whether file exists */
|
||||
bool fileExists( const std::string &filename );
|
||||
std::string baseName( const std::string &filename );
|
||||
std::string dirName( const std::string &filename );
|
||||
std::string pathJoin( const std::string &path1, const std::string &path2 );
|
||||
|
||||
// strings
|
||||
enum ContainsBehaviour
|
||||
@ -51,8 +53,10 @@ namespace MDAL
|
||||
|
||||
/** Return 0 if not possible to convert */
|
||||
size_t toSizeT( const std::string &str );
|
||||
int toInt( const std::string &str );
|
||||
double toDouble( const std::string &str );
|
||||
bool toBool( const std::string &str );
|
||||
bool isNumber( const std::string &str );
|
||||
|
||||
enum SplitBehaviour
|
||||
{
|
||||
|
@ -37,6 +37,8 @@ IF (WITH_INTERNAL_MDAL)
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/mdal_loader.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/mdal_data_model.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/mdal_memory_data_model.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/mdal_driver_manager.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_driver.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_2dm.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_ascii_dat.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_binary_dat.cpp
|
||||
@ -48,6 +50,8 @@ IF (WITH_INTERNAL_MDAL)
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/mdal_loader.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/mdal_data_model.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/mdal_memory_data_model.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/mdal_driver_manager.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_driver.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_2dm.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_ascii_dat.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_binary_dat.hpp
|
||||
@ -57,10 +61,14 @@ IF (WITH_INTERNAL_MDAL)
|
||||
SET(MDAL_LIB_SRCS ${MDAL_LIB_SRCS}
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_hdf5.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_xmdf.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_hec2d.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_flo2d.cpp
|
||||
)
|
||||
SET(MDAL_LIB_HDRS ${MDAL_LIB_HDRS}
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_hdf5.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_xmdf.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_hec2d.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_flo2d.hpp
|
||||
)
|
||||
SET(MDAL_DEPS ${MDAL_DEPS} )
|
||||
SET (HAVE_HDF5 TRUE)
|
||||
@ -82,11 +90,13 @@ IF (WITH_INTERNAL_MDAL)
|
||||
SET(MDAL_LIB_SRCS ${MDAL_LIB_SRCS}
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_cf.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_3di.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_sww.cpp
|
||||
)
|
||||
SET(MDAL_LIB_HDRS ${MDAL_LIB_HDRS}
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_cf.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_3di.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_netcdf.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_sww.hpp
|
||||
)
|
||||
SET (HAVE_NETCDF TRUE)
|
||||
ENDIF(NETCDF_FOUND)
|
||||
|
Loading…
x
Reference in New Issue
Block a user