From 571a0a875a946612aa320766154930f8db91df45 Mon Sep 17 00:00:00 2001 From: Karsten Rink <karsten.rink@ufz.de> Date: Tue, 15 May 2012 14:31:27 +0200 Subject: [PATCH] added XmlIO; added FemEnums + Info-objects; added ProjectData; currently compile errors due to changes in PointVec --- CMakeLists.txt | 2 + FemLib/CMakeLists.txt | 21 ++ FemLib/DistributionInfo.cpp | 26 ++ FemLib/DistributionInfo.h | 39 +++ FemLib/FEMCondition.cpp | 65 +++++ FemLib/FEMCondition.h | 97 +++++++ FemLib/FEMEnums.cpp | 423 +++++++++++++++++++++++++++++++ FemLib/FEMEnums.h | 234 +++++++++++++++++ FemLib/GeoInfo.cpp | 62 +++++ FemLib/GeoInfo.h | 83 ++++++ FemLib/ProcessInfo.cpp | 50 ++++ FemLib/ProcessInfo.h | 94 +++++++ FileIO/CMakeLists.txt | 15 +- FileIO/MeshIO.cpp | 22 +- FileIO/XmlIO/XMLInterface.cpp | 143 +++++++++++ FileIO/XmlIO/XMLInterface.h | 74 ++++++ FileIO/XmlIO/XmlCndInterface.cpp | 316 +++++++++++++++++++++++ FileIO/XmlIO/XmlCndInterface.h | 62 +++++ FileIO/XmlIO/XmlGmlInterface.cpp | 382 ++++++++++++++++++++++++++++ FileIO/XmlIO/XmlGmlInterface.h | 59 +++++ FileIO/XmlIO/XmlGspInterface.cpp | 199 +++++++++++++++ FileIO/XmlIO/XmlGspInterface.h | 44 ++++ FileIO/XmlIO/XmlLutReader.h | 92 +++++++ FileIO/XmlIO/XmlStnInterface.cpp | 315 +++++++++++++++++++++++ FileIO/XmlIO/XmlStnInterface.h | 48 ++++ GeoLib/GEOObjects.cpp | 369 ++++++++++++++++----------- GeoLib/GEOObjects.h | 122 ++++++--- GeoLib/Station.cpp | 231 +++++++++-------- GeoLib/Station.h | 116 +++++---- OGS/CMakeLists.txt | 23 ++ OGS/ProjectData.cpp | 210 +++++++++++++++ OGS/ProjectData.h | 103 ++++++++ 32 files changed, 3773 insertions(+), 368 deletions(-) create mode 100644 FemLib/CMakeLists.txt create mode 100644 FemLib/DistributionInfo.cpp create mode 100644 FemLib/DistributionInfo.h create mode 100644 FemLib/FEMCondition.cpp create mode 100644 FemLib/FEMCondition.h create mode 100644 FemLib/FEMEnums.cpp create mode 100644 FemLib/FEMEnums.h create mode 100644 FemLib/GeoInfo.cpp create mode 100644 FemLib/GeoInfo.h create mode 100644 FemLib/ProcessInfo.cpp create mode 100644 FemLib/ProcessInfo.h create mode 100644 FileIO/XmlIO/XMLInterface.cpp create mode 100644 FileIO/XmlIO/XMLInterface.h create mode 100644 FileIO/XmlIO/XmlCndInterface.cpp create mode 100644 FileIO/XmlIO/XmlCndInterface.h create mode 100644 FileIO/XmlIO/XmlGmlInterface.cpp create mode 100644 FileIO/XmlIO/XmlGmlInterface.h create mode 100644 FileIO/XmlIO/XmlGspInterface.cpp create mode 100644 FileIO/XmlIO/XmlGspInterface.h create mode 100644 FileIO/XmlIO/XmlLutReader.h create mode 100644 FileIO/XmlIO/XmlStnInterface.cpp create mode 100644 FileIO/XmlIO/XmlStnInterface.h create mode 100644 OGS/CMakeLists.txt create mode 100644 OGS/ProjectData.cpp create mode 100644 OGS/ProjectData.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 59031614c5f..6a1a78b2ec2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,10 +34,12 @@ OPTION(OGS_DONT_USE_QT "Disables all Qt specific code." OFF) # Add subdirectories with the projects ADD_SUBDIRECTORY( BaseLib ) +ADD_SUBDIRECTORY( FemLib ) ADD_SUBDIRECTORY( FileIO ) ADD_SUBDIRECTORY( GeoLib ) ADD_SUBDIRECTORY( MathLib ) ADD_SUBDIRECTORY( MeshLib ) +ADD_SUBDIRECTORY( OGS ) ADD_SUBDIRECTORY( SimpleTests/MatrixTests ) ADD_SUBDIRECTORY( SimpleTests/MeshTests ) IF(NOT MSVC) diff --git a/FemLib/CMakeLists.txt b/FemLib/CMakeLists.txt new file mode 100644 index 00000000000..fe18ccfa125 --- /dev/null +++ b/FemLib/CMakeLists.txt @@ -0,0 +1,21 @@ +# Source files +GET_SOURCE_FILES(SOURCES_FEMLIB) +SET ( SOURCES ${SOURCES_FEMLIB}) + +# Create the library +ADD_LIBRARY(FemLib STATIC ${SOURCES}) + +include_directories( + . + ../BaseLib + ../GeoLib + ../MathLib +) + + +target_link_libraries (FemLib + BaseLib + GeoLib + MathLib +) + diff --git a/FemLib/DistributionInfo.cpp b/FemLib/DistributionInfo.cpp new file mode 100644 index 00000000000..df94f24793e --- /dev/null +++ b/FemLib/DistributionInfo.cpp @@ -0,0 +1,26 @@ +/* + * DistributionInfo.cpp + * + * Created on: Sep 28, 2010 + * Author: fischeth + */ + +#include "DistributionInfo.h" + +DistributionInfo::DistributionInfo(FiniteElement::DistributionType dt) : + _dis_type (dt) +{} + +DistributionInfo::~DistributionInfo() +{} + +void DistributionInfo::setProcessDistributionType (FiniteElement::DistributionType dis_type) + +{ + _dis_type = dis_type; +} + +FiniteElement::DistributionType DistributionInfo::getProcessDistributionType () const +{ + return _dis_type; +} diff --git a/FemLib/DistributionInfo.h b/FemLib/DistributionInfo.h new file mode 100644 index 00000000000..0d8bd9b78b4 --- /dev/null +++ b/FemLib/DistributionInfo.h @@ -0,0 +1,39 @@ +/* + * DistributionInfo.h + * + * Created on: Sep 28, 2010 + * Author: TF + */ + +#ifndef DISTRIBUTIONINFO_H_ +#define DISTRIBUTIONINFO_H_ + +// FEM +#include "FEMEnums.h" + +class DistributionInfo +{ +public: + DistributionInfo(FiniteElement::DistributionType dt = FiniteElement::INVALID_DIS_TYPE); + virtual ~DistributionInfo(); + + /** + * Sets the value for the distribution type + * @param dis_type value for primary variable, possible values are documented in enum PrimaryVariable + */ + void setProcessDistributionType (FiniteElement::DistributionType dis_type); + + /** + * Get the distribution type of the process. + * @return the distribution type of the process + */ + FiniteElement::DistributionType getProcessDistributionType () const; + +private: + /** + * the distribution type of the process, see enum DistributionType for valid values + */ + FiniteElement::DistributionType _dis_type; +}; + +#endif /* DISTRIBUTIONINFO_H_ */ diff --git a/FemLib/FEMCondition.cpp b/FemLib/FEMCondition.cpp new file mode 100644 index 00000000000..80d5deec8bc --- /dev/null +++ b/FemLib/FEMCondition.cpp @@ -0,0 +1,65 @@ +/** + * \file FEMCondition.cpp + * 25/11/2010 KR inital implementation + * + */ + +#include "FEMCondition.h" +#include "ProcessInfo.h" + +#include "GEOObjects.h" //for SourceTerm +#include "GridAdapter.h" + +FEMCondition::FEMCondition(const std::string &geometry_name, CondType t) + : _type(t), _geoName("[unspecified]"), _associated_geometry(geometry_name) +{ + this->setProcessType(FiniteElement::INVALID_PROCESS); + this->setProcessPrimaryVariable(FiniteElement::INVALID_PV); + this->setGeoType(GeoLib::INVALID); + this->setProcessDistributionType(FiniteElement::INVALID_DIS_TYPE); +} + +FEMCondition::FEMCondition(const std::string &geometry_name, FiniteElement::ProcessType pt, + FiniteElement::PrimaryVariable pv, GeoLib::GEOTYPE gt, const std::string &gn, + FiniteElement::DistributionType dt, CondType ct) + : ProcessInfo(pt, pv, NULL), GeoInfo(gt, NULL), DistributionInfo(dt), _type(ct), + _geoName(gn), _associated_geometry(geometry_name) +{ +} + +FEMCondition::FEMCondition(const FEMCondition &cond, CondType t) + : ProcessInfo(cond.getProcessType(), cond.getProcessPrimaryVariable(), NULL), + GeoInfo(cond.getGeoType(), cond.getGeoObj()), + DistributionInfo(cond.getProcessDistributionType()), + _type(t), + _geoName(cond.getGeoName()), + _disNodes(cond.getDisNodes()), + _disValues(cond.getDisValues()), + _associated_geometry(cond.getAssociatedGeometryName()) +{ +} + +std::string FEMCondition::condTypeToString(CondType type) +{ + if (type == FEMCondition::BOUNDARY_CONDITION) + return "Boundary Conditions"; + else if (type == FEMCondition::INITIAL_CONDITION) + return "Initial Conditions"; + else if (type == FEMCondition::SOURCE_TERM) + return "Source Terms"; + else + return "Unspecified"; +} + +void FEMCondition::setDisValues(const std::vector< std::pair<size_t, double> > &dis_values) +{ + std::vector<size_t> nodes; + std::vector<double> values; + for (size_t i = 0; i < dis_values.size(); i++) + { + nodes.push_back(dis_values[i].first); + values.push_back(dis_values[i].second); + } + this->_disNodes=nodes; + this->_disValues=values; +} diff --git a/FemLib/FEMCondition.h b/FemLib/FEMCondition.h new file mode 100644 index 00000000000..b16d21044c7 --- /dev/null +++ b/FemLib/FEMCondition.h @@ -0,0 +1,97 @@ +/** + * \file FEMCondition.h + * 25/11/2010 KR inital implementation + * + */ + +#ifndef FEMCONDITION_H +#define FEMCONDITION_H + +#include "DistributionInfo.h" +#include "GeoInfo.h" +#include "GeoObject.h" +#include "Point.h" +#include "ProcessInfo.h" + +#include <vector> + +class CBoundaryCondition; +class CInitialCondition; +class CSourceTerm; + +//class GEOObjects; +class GridAdapter; +#include "GEOObjects.h" + +/** + * \brief Adapter class for handling FEM Conditions in the user Interface + */ +class FEMCondition : public ProcessInfo, public GeoInfo, public DistributionInfo +{ +public: + /// Specifier for types of FEM Conditions + enum CondType { + UNSPECIFIED = 0, + BOUNDARY_CONDITION = 1, + INITIAL_CONDITION = 2, + SOURCE_TERM = 3 + }; + + FEMCondition(const std::string &geometry_name, CondType t = UNSPECIFIED); + FEMCondition(const std::string &geometry_name, + FiniteElement::ProcessType pt = FiniteElement::INVALID_PROCESS, + FiniteElement::PrimaryVariable pv = FiniteElement::INVALID_PV, + GeoLib::GEOTYPE gt = GeoLib::INVALID, + const std::string &gn = "[unspecified]", + FiniteElement::DistributionType dt = FiniteElement::INVALID_DIS_TYPE, CondType ct = UNSPECIFIED); + FEMCondition(const FEMCondition &cond, CondType t); + + ~FEMCondition() {} + + /// Returns the type of the FEM Condition (i.e. BC, IC or ST) + CondType getCondType() const { return _type; } + + /// Returns the value(s) for the distribution + const std::vector<size_t> getDisNodes() const { return _disNodes; } + + /// Returns the value(s) for the distribution + const std::vector<double> getDisValues() const { return _disValues; } + + /// Returns the name of the geo-object the condition is assigned to. This object is part of the associated geometry. + const std::string& getGeoName() const { return _geoName; } + + /// Returns the name of the associated geometry. + const std::string& getAssociatedGeometryName() const { return _associated_geometry; } + + /// Convenience method for setting a single value specifying the distribution. + void setConstantDisValue(double disValue) {_disValues.clear(); _disValues.push_back(disValue); } + + /// Sets a vector of values specifying the distribution. + void setDisValues(const std::vector<size_t> &disNodes, const std::vector<double> &disValues) + { + _disNodes = disNodes; + _disValues = disValues; + } + + /// Sets a vector of values specifying the distribution. + /// The first value specifies the point id, the second the value for that point. + void setDisValues(const std::vector< std::pair<size_t, double> > &dis_values); + + /// Removes all distribution values + void clearDisValues() { _disValues.resize(0); }; + + /// Sets the name of the geo-object the condition is assigned to. + void setGeoName(std::string geoName) { _geoName = geoName; } + + /// Returns the type of the FEM condition as a string. + static std::string condTypeToString(CondType type); + +protected: + CondType _type; + std::string _geoName; + std::vector<size_t> _disNodes; + std::vector<double> _disValues; + std::string _associated_geometry; +}; + +#endif //FEMCONDITION_H diff --git a/FemLib/FEMEnums.cpp b/FemLib/FEMEnums.cpp new file mode 100644 index 00000000000..04abcbc1687 --- /dev/null +++ b/FemLib/FEMEnums.cpp @@ -0,0 +1,423 @@ +/* + * FEMEnums.cpp + * + * Created on: Sep 2, 2010 + * Author: TF + */ + +#include "FEMEnums.h" +#include <cstdlib> +#include <iostream> + +namespace FiniteElement +{ +ProcessType convertProcessType ( const std::string& pcs_type_string ) +{ + if (pcs_type_string.compare ("LIQUID_FLOW") == 0) + return LIQUID_FLOW; + if (pcs_type_string.compare ("FLUID_FLOW") == 0) + return FLUID_FLOW; + if (pcs_type_string.compare ("TWO_PHASE_FLOW") == 0) + return TWO_PHASE_FLOW; + if (pcs_type_string.compare ("RICHARDS_FLOW") == 0) + return RICHARDS_FLOW; + if (pcs_type_string.compare ("OVERLAND_FLOW") == 0) + return OVERLAND_FLOW; + if (pcs_type_string.compare ("GROUNDWATER_FLOW") == 0) + return GROUNDWATER_FLOW; + if (pcs_type_string.compare ("HEAT_TRANSPORT") == 0) + return HEAT_TRANSPORT; + if (pcs_type_string.compare ("DEFORMATION") == 0) + return DEFORMATION; + if (pcs_type_string.compare ("DEFORMATION_FLOW") == 0) + return DEFORMATION_FLOW; + if (pcs_type_string.compare ("DEFORMATION_DYNAMIC") == 0) + return DEFORMATION_DYNAMIC; + if (pcs_type_string.compare ("MASS_TRANSPORT") == 0) + return MASS_TRANSPORT; + if (pcs_type_string.compare ("MULTI_PHASE_FLOW") == 0) + return MULTI_PHASE_FLOW; + if (pcs_type_string.compare ("DEFORMATION_H2") == 0) + return DEFORMATION_H2; + if (pcs_type_string.compare ("AIR_FLOW") == 0) + return AIR_FLOW; + if (pcs_type_string.compare ("FLUID_MOMENTUM") == 0) + return FLUID_MOMENTUM; + if (pcs_type_string.compare ("RANDOM_WALK") == 0) + return RANDOM_WALK; + if (pcs_type_string.compare ("FLUX") == 0) + return FLUX; + if (pcs_type_string.compare ("PS_GLOBAL") == 0) + return PS_GLOBAL; + if (pcs_type_string.compare ("NO_PCS") == 0) + return NO_PCS; + if (pcs_type_string.compare ("PTC_FLOW") == 0) + return PTC_FLOW; + //else + //std::cout << "WARNING in convertProcessType: process type #" << pcs_type_string << + //"# unknown" << std::endl; + return INVALID_PROCESS; +} + +std::string convertProcessTypeToString ( ProcessType pcs_type ) +{ + if (pcs_type == LIQUID_FLOW) + return "LIQUID_FLOW"; + if (pcs_type == FLUID_FLOW) + return "FLUID_FLOW"; + if (pcs_type == TWO_PHASE_FLOW) + return "TWO_PHASE_FLOW"; + if (pcs_type == RICHARDS_FLOW) + return "RICHARDS_FLOW"; + if (pcs_type == OVERLAND_FLOW) + return "OVERLAND_FLOW"; + if (pcs_type == GROUNDWATER_FLOW) + return "GROUNDWATER_FLOW"; + if (pcs_type == HEAT_TRANSPORT) + return "HEAT_TRANSPORT"; + if (pcs_type == DEFORMATION) + return "DEFORMATION"; + if (pcs_type == DEFORMATION_FLOW) + return "DEFORMATION_FLOW"; + if (pcs_type == DEFORMATION_DYNAMIC) + return "DEFORMATION_DYNAMIC"; + if (pcs_type == MASS_TRANSPORT) + return "MASS_TRANSPORT"; + if (pcs_type == MULTI_PHASE_FLOW) + return "MULTI_PHASE_FLOW"; + if (pcs_type == DEFORMATION_H2) + return "DEFORMATION_H2"; + if (pcs_type == AIR_FLOW) + return "AIR_FLOW"; + if (pcs_type == FLUID_MOMENTUM) + return "FLUID_MOMENTUM"; + if (pcs_type == RANDOM_WALK) + return "RANDOM_WALK"; + if (pcs_type == FLUX) + return "FLUX"; + if (pcs_type == PS_GLOBAL) + return "PS_GLOBAL"; + if (pcs_type == PTC_FLOW) + return "PTC_FLOW"; + if (pcs_type == NO_PCS) + return "NO_PCS"; + return "INVALID_PROCESS"; +} + +bool isFlowProcess (ProcessType pcs_type) +{ + if ( pcs_type == LIQUID_FLOW || pcs_type == FLUID_FLOW + || pcs_type == RICHARDS_FLOW || pcs_type == GROUNDWATER_FLOW + || pcs_type == PS_GLOBAL || pcs_type == MULTI_PHASE_FLOW + || pcs_type == DEFORMATION_FLOW || pcs_type == DEFORMATION_H2 + || pcs_type == TWO_PHASE_FLOW || pcs_type == OVERLAND_FLOW + || pcs_type == AIR_FLOW || pcs_type == PTC_FLOW) + return true; + return false; +} + +bool isMultiFlowProcess (ProcessType pcs_type) +{ + if (pcs_type == PS_GLOBAL || + pcs_type == MULTI_PHASE_FLOW || + pcs_type == TWO_PHASE_FLOW || + pcs_type == DEFORMATION_H2) + return true; + return false; +} + +bool isDeformationProcess (ProcessType pcs_type) +{ + if (pcs_type == DEFORMATION || pcs_type == DEFORMATION_H2 || + pcs_type == DEFORMATION_FLOW || pcs_type == DEFORMATION_DYNAMIC) + return true; + return false; +} + +const std::list<std::string> getAllProcessNames() +{ + size_t count(1); + std::list<std::string> enum_names; + + while (count != PROCESS_END) + { + enum_names.push_back( convertProcessTypeToString(static_cast<ProcessType>(count++)) ); + } + return enum_names; +} + + +PrimaryVariable convertPrimaryVariable ( const std::string& pcs_pv_string ) +{ + if (pcs_pv_string.compare ("PRESSURE1") == 0) + return PRESSURE; + if (pcs_pv_string.compare ("PRESSURE2") == 0) + return PRESSURE2; + if (pcs_pv_string.compare ("PRESSURE_RATE1") == 0) + return PRESSURE_RATE1; + if (pcs_pv_string.compare ("SATURATION1") == 0) + return SATURATION; + if (pcs_pv_string.compare ("SATURATION2") == 0) + return SATURATION2; + if (pcs_pv_string.compare ("TEMPERATURE1") == 0) + return TEMPERATURE; + if (pcs_pv_string.compare ("DISPLACEMENT_X1") == 0) + return DISPLACEMENT_X; + if (pcs_pv_string.compare ("DISPLACEMENT_Y1") == 0) + return DISPLACEMENT_Y; + if (pcs_pv_string.compare ("DISPLACEMENT_Z1") == 0) + return DISPLACEMENT_Z; + if (pcs_pv_string.compare ("CONCENTRATION1") == 0) + return CONCENTRATION; + if (pcs_pv_string.compare ("HEAD") == 0) + return HEAD; + if (pcs_pv_string.compare ("VELOCITY_DM_X") == 0) + return VELOCITY_DM_X; + if (pcs_pv_string.compare ("VELOCITY_DM_Y") == 0) + return VELOCITY_DM_Y; + if (pcs_pv_string.compare ("VELOCITY_DM_Z") == 0) + return VELOCITY_DM_Z; + if (pcs_pv_string.compare ("VELOCITY1_X") == 0) + return VELOCITY1_X; + if (pcs_pv_string.compare ("VELOCITY1_Y") == 0) + return VELOCITY1_Y; + if (pcs_pv_string.compare ("VELOCITY1_Z") == 0) + return VELOCITY1_Z; + if (pcs_pv_string.compare ("STRESS_XX") == 0) + return STRESS_XX; + if (pcs_pv_string.compare ("STRESS_XY") == 0) + return STRESS_XY; + if (pcs_pv_string.compare ("STRESS_XZ") == 0) + return STRESS_XZ; + if (pcs_pv_string.compare ("STRESS_YY") == 0) + return STRESS_YY; + if (pcs_pv_string.compare ("STRESS_YZ") == 0) + return STRESS_YZ; + if (pcs_pv_string.compare ("STRESS_ZZ") == 0) + return STRESS_ZZ; + if (pcs_pv_string.compare ("ACCELERATION_X1") == 0) + return ACCELERATION_X1; + if (pcs_pv_string.compare ("ACCELERATION_Y1") == 0) + return ACCELERATION_Y1; + if (pcs_pv_string.compare ("ACCELERATION_Z1") == 0) + return ACCELERATION_Z1; + if (pcs_pv_string.compare ("EXCAVATION") == 0) + return EXCAVATION; + if (pcs_pv_string.compare ("STRAIN_XX") == 0) + return STRAIN_XX; + if (pcs_pv_string.compare ("STRAIN_XY") == 0) + return STRAIN_XY; + if (pcs_pv_string.compare ("STRAIN_XZ") == 0) + return STRAIN_XZ; + if (pcs_pv_string.compare ("STRAIN_YY") == 0) + return STRAIN_YY; + if (pcs_pv_string.compare ("STRAIN_YZ") == 0) + return STRAIN_YZ; + if (pcs_pv_string.compare ("STRAIN_ZZ") == 0) + return STRAIN_ZZ; + if (pcs_pv_string.compare ("STRAIN_PLS") == 0) + return STRAIN_PLS; + //else + //{ + //std::cout << "convertPrimaryVariable #" << pcs_pv_string << "# not found" << std::endl; + //exit (1); + //} + return INVALID_PV; +} + +std::string convertPrimaryVariableToString ( PrimaryVariable pcs_pv ) +{ + if (pcs_pv == PRESSURE) + return "PRESSURE1"; + if (pcs_pv == PRESSURE2) + return "PRESSURE2"; + if (pcs_pv == PRESSURE_RATE1) + return "PRESSURE_RATE1"; + if (pcs_pv == SATURATION) + return "SATURATION1"; + if (pcs_pv == SATURATION2) + return "SATURATION2"; + if (pcs_pv == TEMPERATURE) + return "TEMPERATURE1"; + if (pcs_pv == DISPLACEMENT_X) + return "DISPLACEMENT_X1"; + if (pcs_pv == DISPLACEMENT_Y) + return "DISPLACEMENT_Y1"; + if (pcs_pv == DISPLACEMENT_Z) + return "DISPLACEMENT_Z1"; + if (pcs_pv == CONCENTRATION) + return "CONCENTRATION1"; + if (pcs_pv == HEAD) + return "HEAD"; + if (pcs_pv == VELOCITY_DM_X) + return "VELOCITY_DM_X"; + if (pcs_pv == VELOCITY_DM_Y) + return "VELOCITY_DM_Y"; + if (pcs_pv == VELOCITY_DM_Z) + return "VELOCITY_DM_Z"; + if (pcs_pv == VELOCITY1_X) + return "VELOCITY1_X"; + if (pcs_pv == VELOCITY1_Y) + return "VELOCITY1_Y"; + if (pcs_pv == VELOCITY1_Z) + return "VELOCITY1_Z"; + if (pcs_pv == STRESS_XX) + return "STRESS_XX"; + if (pcs_pv == STRESS_XY) + return "STRESS_XY"; + if (pcs_pv == STRESS_XZ) + return "STRESS_XZ"; + if (pcs_pv == STRESS_YY) + return "STRESS_YY"; + if (pcs_pv == STRESS_YZ) + return "STRESS_YZ"; + if (pcs_pv == STRESS_ZZ) + return "STRESS_ZZ"; + if (pcs_pv == STRAIN_XX) return "STRAIN_XX"; + if (pcs_pv == STRAIN_XY) return "STRAIN_XY"; + if (pcs_pv == STRAIN_XZ) return "STRAIN_XZ"; + if (pcs_pv == STRAIN_YY) return "STRAIN_YY"; + if (pcs_pv == STRAIN_YZ) return "STRAIN_YZ"; + if (pcs_pv == STRAIN_ZZ) return "STRAIN_ZZ"; + if (pcs_pv == STRAIN_PLS) return "STRAIN_PLS"; + if (pcs_pv == ACCELERATION_X1) + return "ACCELERATION_X1"; + if (pcs_pv == ACCELERATION_Y1) + return "ACCELERATION_Y1"; + if (pcs_pv == ACCELERATION_Z1) + return "ACCELERATION_Z1"; + if (pcs_pv == EXCAVATION) + return "EXCAVATION"; + return "INVALID_PRIMARY_VARIABLE"; +} + +const std::list<std::string> getAllPrimaryVariableNames() +{ + size_t count(1); + std::list<std::string> enum_names; + + while (count != PV_END) + { + enum_names.push_back( convertPrimaryVariableToString(static_cast<PrimaryVariable>(count++)) ); + } + return enum_names; +} + +DistributionType convertDisType(const std::string& dis_type_string) +{ + if (dis_type_string.compare("CONSTANT") == 0) + return CONSTANT; + if (dis_type_string.compare("ANALYTICAL") == 0) + return ANALYTICAL; + if (dis_type_string.compare("AVERAGE") == 0) + return AVERAGE; + if (dis_type_string.compare("CONSTANT_GEO") == 0) + return CONSTANT_GEO; + if (dis_type_string.compare("GRADIENT") == 0) + return GRADIENT; + if (dis_type_string.compare("RESTART") == 0) + return RESTART; + if (dis_type_string.compare("LINEAR") == 0) + return LINEAR; + if (dis_type_string.compare("POINT") == 0) + return POINT; + if (dis_type_string.compare("CONSTANT_NEUMANN") == 0) + return CONSTANT_NEUMANN; + if (dis_type_string.compare("LINEAR_NEUMANN") == 0) + return LINEAR_NEUMANN; + if (dis_type_string.compare("NORMALDEPTH") == 0) + return NORMALDEPTH; + if (dis_type_string.compare("CRITICALDEPTH") == 0) + return CRITICALDEPTH; + if (dis_type_string.compare("GREEN_AMPT") == 0) + return GREEN_AMPT; + if (dis_type_string.compare("SYSTEM_DEPENDENT") == 0) + return SYSTEM_DEPENDENT; + if (dis_type_string.compare("PRECIPITATION") == 0) + return PRECIPITATION; + if (dis_type_string.compare("DIRECT") == 0) + return DIRECT; + if (dis_type_string.compare("FUNCTION") == 0) + return FUNCTION; //24.08.2011. WW + else + { + std::cout << "convertDisType #" << dis_type_string << "# not found" + << std::endl; + exit(1); + } + return INVALID_DIS_TYPE; +} + +std::string convertDisTypeToString(DistributionType dis_type) +{ + if (dis_type == ANALYTICAL) + return "ANALYTICAL"; + if (dis_type == AVERAGE) + return "AVERAGE"; + if (dis_type == CONSTANT) + return "CONSTANT"; + if (dis_type == CONSTANT_GEO) + return "CONSTANT_GEO"; + if (dis_type == GRADIENT) + return "GRADIENT"; + if (dis_type == RESTART) + return "RESTART"; + if (dis_type == LINEAR) + return "LINEAR"; + if (dis_type == POINT) + return "POINT"; + if (dis_type == CONSTANT_NEUMANN) + return "CONSTANT_NEUMANN"; + if (dis_type == LINEAR_NEUMANN) + return "LINEAR_NEUMANN"; + if (dis_type == NORMALDEPTH) + return "NORMALDEPTH"; + if (dis_type == CRITICALDEPTH) + return "CRITICALDEPTH"; + if (dis_type == GREEN_AMPT) + return "GREEN_AMPT"; + if (dis_type == SYSTEM_DEPENDENT) + return "SYSTEM_DEPENDENT"; + if (dis_type == PRECIPITATION) + return "PRECIPITATION"; + if (dis_type == DIRECT) + return "DIRECT"; + if (dis_type == FUNCTION) + return "FUNCTION"; //24.08.2011. WW + + return "INVALID_DIS_TYPE"; +} + +const std::list<std::string> getAllDistributionNames() +{ + size_t count(1); + std::list<std::string> enum_names; + + while (count != DIS_END) + { + enum_names.push_back( convertDisTypeToString(static_cast<DistributionType>(count++)) ); + } + return enum_names; +} + +ErrorMethod convertErrorMethod(const std::string& error_method_string) +{ + if (error_method_string.compare("LMAX") == 0) + return LMAX; + if (error_method_string.compare("ENORM") == 0) + return ENORM; + if (error_method_string.compare("EVNORM") == 0) + return EVNORM; + if (error_method_string.compare("ERNORM") == 0) + return ERNORM; + if (error_method_string.compare("BNORM") == 0) + return BNORM; + else + { + std::cout << "convertErrorMethod #" << error_method_string << "# not found"<< std::endl; + exit(1); + } + return INVALID_ERROR_METHOD; +} + +} // end namespace FiniteElement diff --git a/FemLib/FEMEnums.h b/FemLib/FEMEnums.h new file mode 100644 index 00000000000..805eae4fedc --- /dev/null +++ b/FemLib/FEMEnums.h @@ -0,0 +1,234 @@ +/** + * \file FEMEnums.h + * 31/08/2010 KR inital implementation + * + */ + +#ifndef FEMENUMS_H +#define FEMENUMS_H + +#include <limits> +#include <string> +#include <list> + +namespace FiniteElement +{ +/** \brief Types of physical processes supported by OpenGeoSys. + * If you change this enum, make sure you apply the changes to + * the functions convertPorcessType(), convertProcessTypeToString(), + * isFlowProcess() and isDeformationProcess() + */ +enum ProcessType +{ + INVALID_PROCESS = 0, //!< INVALID_PROCESS + AIR_FLOW, //!< AIR_FLOW + /// M process, single/multi-phase flow + DEFORMATION, //!< DEFORMATION + DEFORMATION_DYNAMIC, //!< ... + /// C process, single/multi-phase flow + DEFORMATION_FLOW, //!< DEFORMATION_FLOW + /// H2M monolithic + DEFORMATION_H2, //!< DEFORMATION_H2 + FLUID_FLOW, + FLUID_MOMENTUM, // BC only + FLUX, + /// H process, incompressible flow + GROUNDWATER_FLOW, //!< GROUNDWATER_FLOW + /// T process, single/multi-phase flow + HEAT_TRANSPORT, //!< HEAT_TRANSPORT + /// H process, incompressible flow + LIQUID_FLOW, //!< LIQUID_FLOW + MASS_TRANSPORT, //!< MASS_TRANSPORT + MULTI_PHASE_FLOW, //!< MULTI_PHASE_FLOW + NO_PCS, //!< NO_PCS + /// H process, incompressible flow + OVERLAND_FLOW, //!< OVERLAND_FLOW + PS_GLOBAL, //!< PS_GLOBAL + PTC_FLOW, // Fluid flow coupled with heat transport + RANDOM_WALK, //!< RANDOM_WALK + /// H process, incompressible flow + RICHARDS_FLOW, //!< RICHARDS_FLOW + /// H2 process, compressible flow + TWO_PHASE_FLOW, //!< TWO_PHASE_FLOW + // make sure that this is always the last entry (important for iterating over the enum entries)! + PROCESS_END +}; + +/** + * \brief Convert the given string into the appropriate enum value. + * @param pcs_type_string string describing a process type + * @return enum value describing process type + */ +ProcessType convertProcessType ( const std::string& pcs_type_string ); + +/** + * \brief Convert the given enum value into the appropriate string. + * @param pcs_type process type described by the enum ProcessType + * @return string describing the process type + */ +std::string convertProcessTypeToString ( ProcessType pcs_type ); + +/** + * \brief Checks if the given pcs_type variable corresponds to a flow type of the enum ProcessType. + * @param pcs_type value of enum ProcessType + * @return true if pcs_type describes a flow process, else false + */ +bool isFlowProcess (ProcessType pcs_type); + +/** + * \brief Checks if the given pcs_type variable corresponds to a multiphase flow type of the enum ProcessType. + * @param pcs_type value of enum ProcessType + * @return true if pcs_type describes a flow process, else false + */ +bool isMultiFlowProcess (ProcessType pcs_type); + +/** + * \brief Checks if the given pcs_type variable corresponds to a deformation type of the enum ProcessType. + * @param pcs_type value of enum ProcessType + * @return true if pcs_type describes a deformation process, else false + */ +bool isDeformationProcess (ProcessType pcs_type); + +/// Returns a list of strings containing all entries in the ProcessType enum. +const std::list<std::string> getAllProcessNames(); + +/** + * \brief Contains all values for primary variables actually handled by OGS. + */ +enum PrimaryVariable +{ + INVALID_PV = 0, //!< INVALID_PV + ACCELERATION_X1, //!< ACCELERATION_X1 + ACCELERATION_Y1, //!< ACCELERATION_Y1 + ACCELERATION_Z1, //!< ACCELERATION_Z1 + /// Mass transport + CONCENTRATION, //!< CONCENTRATION + /// Deformation + DISPLACEMENT_X, //!< DISPLACEMENT_X + /// Deformation + DISPLACEMENT_Y, //!< DISPLACEMENT_Y + /// Deformation + DISPLACEMENT_Z, //!< DISPLACEMENT_Z + EXCAVATION, // ST + HEAD, //!< HEAD + /// Flow (phase) + PRESSURE, //!< PRESSURE + PRESSURE2, //!< PRESSURE2 + PRESSURE_RATE1, // OUT + SATURATION, //!< SATURATION + SATURATION2, //!< SATURATION2 + STRAIN_XX, // Output + STRAIN_XY, // Output + STRAIN_XZ, // Output + STRAIN_YY, // Output + STRAIN_YZ, // Output + STRAIN_ZZ, // Output + STRAIN_PLS, // Output + STRESS_XX, // IC + STRESS_XY, // IC + STRESS_XZ, // IC + STRESS_YY, // IC + STRESS_YZ, // IC + STRESS_ZZ, // IC + /// Heat transport + TEMPERATURE, //!< TEMPERATURE + VELOCITY_DM_X, //!< VELOCITY_DM_X + VELOCITY_DM_Y, //!< VELOCITY_DM_Y + VELOCITY_DM_Z, //!< VELOCITY_DM_Z + VELOCITY1_X, + VELOCITY1_Y, + VELOCITY1_Z, + // make sure that this is always the last entry (important for iterating over the enum entries)! + PV_END +}; + +/** + * \brief Converts the given string into the appropriate enum value. + * @param pcs_pv_string string describing the primary variable + * @return enum value describing the primary variable of the process + */ +//!< PrimaryVariable +PrimaryVariable convertPrimaryVariable ( const std::string& pcs_pv_string ); + +/** + * \brief Converts the given enum value into the appropriate string. + * @param pcs_pv primary variable described by the enum ProcessType + * @return string describing the process type + */ +std::string convertPrimaryVariableToString ( PrimaryVariable pcs_pv ); + +/// Returns a list of strings containing all entries in the PrimaryVariable enum. +const std::list<std::string> getAllPrimaryVariableNames(); + +enum DistributionType +{ + INVALID_DIS_TYPE = 0, + ANALYTICAL, // ST + AVERAGE, + CONSTANT, // IC, BC, ST + CONSTANT_GEO, + CONSTANT_NEUMANN, // ST + CRITICALDEPTH, // ST + DIRECT, + FUNCTION, + GRADIENT, // IC + GREEN_AMPT, // ST + RESTART, // IC + LINEAR, // BC, ST + LINEAR_NEUMANN, // ST + NORMALDEPTH, // ST + POINT, // BC + PRECIPITATION, + SYSTEM_DEPENDENT, // ST + // Sort of Neumann BC //WW + // make sure that this is always the last entry (important for iterating over the enum entries)! + DIS_END +}; + +/** + * \brief Converts the given string into the appropriate enum value. + * @param pcs_pv_string string describing the primary variable + * @return enum value describing the primary variable of the process + */ +DistributionType convertDisType(const std::string& dis_type_string); + +/** + * \brief Converts the given enum value into the appropriate string. + * @param pcs_pv primary variable described by the enum ProcessType + * @return string describing the process type + */ +std::string convertDisTypeToString(DistributionType dis_type); + +/// Returns a list of strings containing all entries in the DistributionType enum. +const std::list<std::string> getAllDistributionNames(); + +/** \brief Types of error method supported by OpenGeoSys. + * If you change this enum, make sure you apply the changes to + * the functions convertErrorMethod(), convertErrorMethodToString() + Non-Linear and Coupling options (see also CRFProcess::CalcIterationNODError()): + --> LMAX: max(|x1-x0|) -- Infinity norm: Local max error (across all elements) of solution vector delta (absolute error). Tolerance required for each primary variable. + --> ENORM: |x1-x0| -- Euclidian norm: Norm of the solution vector delta (absolute error). Norm taken over entire solution vector (all primary variables) and checked against a single tolerance. + --> EVNORM: |x1-x0| -- Euclidian varient norm: Norm of the solution vector delta (absolute error). Norm taken over solution vector of each primary variable, checked againes a tolerence specific to each variable. + --> ERNORM: |(x1-x0)/x0)| -- Euclidian Relative norm: Norm of the solution vector delta divided by the norm of the solution vector. A single tolerance applied to all primary variables. + --> BNORM: -- OGS classic treatment of newton methods. ENORM error tolerance plus RHS ("B") control. (note: other error methods (i.e. ENORM) will also work well for NEWTON scheme) + */ +enum ErrorMethod +{ + INVALID_ERROR_METHOD = 0, + LMAX, + ENORM, + EVNORM, + ERNORM, + BNORM +}; + +/** + * \brief Convert the given string into the appropriate enum value. + * @param pcs_type_string string describing an error method + * @return enum value describing error method + */ +ErrorMethod convertErrorMethod ( const std::string& error_method_string ); + +} // end namespace FiniteElement + +#endif //FEMENUMS_H diff --git a/FemLib/GeoInfo.cpp b/FemLib/GeoInfo.cpp new file mode 100644 index 00000000000..36aed22e8cc --- /dev/null +++ b/FemLib/GeoInfo.cpp @@ -0,0 +1,62 @@ +/* + * GeoInfo.cpp + * + * Created on: Jun 18, 2010 + * Author: TF + */ + +// STL +#include <limits> + +// FEM +#include "GeoInfo.h" + +GeoInfo::GeoInfo() : + _geo_type(GEOLIB::INVALID), _geo_obj(NULL) +{} + +GeoInfo::GeoInfo(GEOLIB::GEOTYPE geo_type, const GEOLIB::GeoObject* geo_obj) : + _geo_type(geo_type), _geo_obj(geo_obj) +{} + +GeoInfo::~GeoInfo() +{} + +GEOLIB::GEOTYPE GeoInfo::getGeoType () const +{ + return _geo_type; +} + +std::string GeoInfo::getGeoTypeAsString () const +{ + switch (_geo_type) + { + case GEOLIB::POINT: + return "POINT"; + case GEOLIB::POLYLINE: + return "POLYLINE"; + case GEOLIB::SURFACE: + return "SURFACE"; + case GEOLIB::VOLUME: + return "VOLUME"; + case GEOLIB::GEODOMAIN: + return "DOMAIN"; + default: + return ""; + } +} + +void GeoInfo::setGeoType (GEOLIB::GEOTYPE geo_type) +{ + _geo_type = geo_type; +} + +const GEOLIB::GeoObject* GeoInfo::getGeoObj () const +{ + return _geo_obj; +} + +void GeoInfo::setGeoObj (const GEOLIB::GeoObject* geo_obj) +{ + _geo_obj = geo_obj; +} diff --git a/FemLib/GeoInfo.h b/FemLib/GeoInfo.h new file mode 100644 index 00000000000..8cb4d2995af --- /dev/null +++ b/FemLib/GeoInfo.h @@ -0,0 +1,83 @@ +/* + * GeoInfo.h + * + * Created on: Jun 18, 2010 + * Author: TF + */ + +#ifndef GEOINFO_H_ +#define GEOINFO_H_ + +// GEO +#include "GeoObject.h" +#include "GeoType.h" + +/** + * \brief GeoInfo stores the type of the geometric entity and + * the index within the vector the geometric entity is + * managed. Possible geometric entities are documented in + * GeoType.h. + */ +class GeoInfo +{ +public: + /** + * standard constructor. You need to set the attributes via + * setGeoType() and setGeoObj()! + */ + GeoInfo (); + /** + * The constructor of a GeoInfo object initializes the + * attributes of the object. + * @param geo_type the type of the geometric entity. + * Possible geometric entities are documented in GeoType.h. + * @param geo_obj the pointer to an object of class GeoObject + */ + GeoInfo(GeoLib::GEOTYPE geo_type, const GeoLib::GeoObject* geo_obj = NULL); + /** + * virtual destructor - destroys the object + */ + virtual ~GeoInfo(); + + /** + * getter method for the geo type + * @sa enum GeoType + * @return the geo type + */ + GeoLib::GEOTYPE getGeoType () const; + + /** + * get the type as a string for log output + * @return + */ + std::string getGeoTypeAsString () const; + + /** + * getter for the pointer to the object + * @return + */ + const GeoLib::GeoObject* getGeoObj () const; + + /** + * setter for the geo type + * @sa enum GeoType + * @param geo_type type of the geometric entity + */ + void setGeoType (GeoLib::GEOTYPE geo_type); + /** + * setter for the pointer to the GeoObject object + * @param geo_obj an instance of class GeoObject + */ + void setGeoObj (const GeoLib::GeoObject* geo_obj); + +protected: + /** + * type of the geometric entity. @sa enum GeoType + */ + GeoLib::GEOTYPE _geo_type; + /** + * pointer to geometric object (GeoLib::Point, GeoLib::Polyline, GeoLib::Surface, ...) + */ + const GeoLib::GeoObject* _geo_obj; +}; +#endif /* GEOINFO_H_ */ diff --git a/FemLib/ProcessInfo.cpp b/FemLib/ProcessInfo.cpp new file mode 100644 index 00000000000..e3a65521bb1 --- /dev/null +++ b/FemLib/ProcessInfo.cpp @@ -0,0 +1,50 @@ +/* + * \file ProcessInfo.cpp + * + * Created on: Sep 2, 2010 + * Author: TF + */ + +#include "rf_pcs.h" +#include <ProcessInfo.h> + +ProcessInfo::ProcessInfo() : + _pcs_type (FiniteElement::INVALID_PROCESS), _pcs_pv (FiniteElement::INVALID_PV), _pcs (NULL) +{} + +ProcessInfo::ProcessInfo (FiniteElement::ProcessType pcs_type, FiniteElement::PrimaryVariable pcs_pv, CRFProcess* pcs) : + _pcs_type (pcs_type), _pcs_pv (pcs_pv), _pcs (pcs) +{} + +void ProcessInfo::setProcessType (FiniteElement::ProcessType pcs_type) +{ + _pcs_type = pcs_type; +} + +void ProcessInfo::setProcessPrimaryVariable (FiniteElement::PrimaryVariable pcs_pv) +{ + _pcs_pv = pcs_pv; +} + +void ProcessInfo::setProcess (CRFProcess* pcs) +{ + _pcs = pcs; +} + +FiniteElement::ProcessType ProcessInfo::getProcessType () const +{ + return _pcs_type; +} + +FiniteElement::PrimaryVariable ProcessInfo::getProcessPrimaryVariable () const +{ + return _pcs_pv; +} + +CRFProcess* ProcessInfo::getProcess () const +{ + return _pcs; +} + +ProcessInfo::~ProcessInfo() +{} diff --git a/FemLib/ProcessInfo.h b/FemLib/ProcessInfo.h new file mode 100644 index 00000000000..7c915ae78c0 --- /dev/null +++ b/FemLib/ProcessInfo.h @@ -0,0 +1,94 @@ +/* + * \file ProcessInfo.h + * + * Created on: Sep 2, 2010 + * Author: TF + */ + +#ifndef PROCESSINFO_H_ +#define PROCESSINFO_H_ + +// FEM +#include "FEMEnums.h" +class CRFProcess; + +/** + * \brief Class ProcessInfo stores the process type, + * an value for the primary variable of the process and + * a pointer to the process object. + */ +class ProcessInfo +{ +public: + /** + * Default constructor, initializes pcs_type with ProcessType::INVALID_PROCESS, + * pcs_pv with PrimaryVariable::INVALID_PV and + * the pointer to the process with NULL. The user should set the values + * with the appropriate set methods. + * @return + */ + ProcessInfo(); + + /** + * constructor initializing all attributes of the object with the given values + * @param pcs_type process type (\sa enum ProcessType) + * @param pcs_pv type of primary variable (\sa enum PrimaryVariable) + * @param pcs a pointer to the process + * @return + */ + ProcessInfo (FiniteElement::ProcessType pcs_type, FiniteElement::PrimaryVariable pcs_pv, CRFProcess* pcs); + + /** + * Sets the process type. + * @param pcs_type the process type, for valid values see enum ProcessType + */ + void setProcessType (FiniteElement::ProcessType pcs_type); + + /** + * Sets the value for the primary variable + * @param pcs_pv value for primary variable, possible values are documented in enum PrimaryVariable + */ + void setProcessPrimaryVariable (FiniteElement::PrimaryVariable pcs_pv); + + /** + * Sets the value for the pointer to an object of class CRFProcess. + * @param pcs the pointer to an object of class CRFProcess + */ + void setProcess (CRFProcess* pcs); + + /** + * Get the process type. + * @return the process type + */ + FiniteElement::ProcessType getProcessType () const; + + /** + * Get the primary variable of the process. + * @return the primary variable of the process + */ + FiniteElement::PrimaryVariable getProcessPrimaryVariable () const; + + /** + * Get a pointer to an object of type CRFProcess. + * @return a pointer to an object of type CRFProcess + */ + CRFProcess* getProcess () const; + + virtual ~ProcessInfo(); + +protected: + /** + * process type, see enum ProcessType for valid values + */ + FiniteElement::ProcessType _pcs_type; + /** + * the primary variable of the process, see enum PrimaryVariable for valid values + */ + FiniteElement::PrimaryVariable _pcs_pv; + + /** + * pointer to the object of class CRFProcess + */ + CRFProcess* _pcs; +}; +#endif /* PROCESSINFO_H_ */ diff --git a/FileIO/CMakeLists.txt b/FileIO/CMakeLists.txt index 200660be928..edc18b8e4f6 100644 --- a/FileIO/CMakeLists.txt +++ b/FileIO/CMakeLists.txt @@ -2,15 +2,22 @@ GET_SOURCE_FILES(SOURCES_FILEIO) SET ( SOURCES ${SOURCES_FILEIO}) +IF (QT4_FOUND) + GET_SOURCE_FILES(SOURCES_XML XmlIO) + SET ( SOURCES ${SOURCES} ${SOURCES_XML}) +ENDIF (QT4_FOUND) + # Create the library ADD_LIBRARY(FileIO STATIC ${SOURCES}) include_directories( . - ../BaseLib - ../GeoLib - ../MathLib - ../MeshLib + ${CMAKE_SOURCE_DIR}/BaseLib + ${CMAKE_SOURCE_DIR}/FemLib + ${CMAKE_SOURCE_DIR}/GeoLib + ${CMAKE_SOURCE_DIR}/MathLib + ${CMAKE_SOURCE_DIR}/MeshLib + ${CMAKE_SOURCE_DIR}/OGS ) target_link_libraries (FileIO diff --git a/FileIO/MeshIO.cpp b/FileIO/MeshIO.cpp index 6b12458ccc7..b01edcf9c0e 100644 --- a/FileIO/MeshIO.cpp +++ b/FileIO/MeshIO.cpp @@ -30,12 +30,7 @@ MeshIO::MeshIO() MeshLib::Mesh* MeshIO::loadMeshFromFile(const std::string& file_name) { std::cout << "Read mesh ... " << std::endl; -/* - #ifndef NDEBUG - QTime myTimer; - myTimer.start(); - #endif - */ + std::ifstream in (file_name.c_str(),std::ios::in); if (!in.is_open()) { @@ -105,11 +100,7 @@ MeshLib::Mesh* MeshIO::loadMeshFromFile(const std::string& file_name) std::cout << "Nr. Nodes: " << nodes.size() << std::endl; std::cout << "Nr. Elements: " << elements.size() << std::endl; - /* - #ifndef NDEBUG - std::cout << "Loading time: " << myTimer.elapsed() << " ms" << std::endl; - #endif - */ + in.close(); return mesh; } else @@ -171,14 +162,7 @@ MeshLib::Element* MeshIO::readElement(const std::string& line, const std::vector default: elem = NULL; } - - - /* - neighbors.resize(nfaces); - for (unsigned i = 0; i < nfaces; i++) - neighbors[i] = NULL; - */ - + return elem; } diff --git a/FileIO/XmlIO/XMLInterface.cpp b/FileIO/XmlIO/XMLInterface.cpp new file mode 100644 index 00000000000..0518da99a8e --- /dev/null +++ b/FileIO/XmlIO/XMLInterface.cpp @@ -0,0 +1,143 @@ +/** + * \file XMLInterface.cpp + * 18/02/2010 KR Initial implementation + */ + +#include "ProjectData.h" +#include "XMLInterface.h" + +//#include "Configure.h" + +#include <QCryptographicHash> +#include <QFileInfo> +#ifdef QT_USE_QTXMLPATTERNS +#include <QtXmlPatterns/QXmlSchema> +#include <QtXmlPatterns/QXmlSchemaValidator> +#endif // QT_USE_QTXMLPATTERNS + +namespace FileIO +{ + +XMLInterface::XMLInterface(ProjectData* project, const std::string &schemaFile) +: _project(project), _exportName(""), _schemaName(schemaFile) +{ +} + +int XMLInterface::isValid(const QString &fileName) const +{ +#ifdef QT_USE_QTXMLPATTERNS + QXmlSchema schema; + schema.load( QUrl::fromLocalFile((QString::fromStdString(_schemaName))) ); + + if ( schema.isValid() ) + { + QXmlSchemaValidator validator( schema ); + if ( validator.validate( QUrl::fromLocalFile((fileName))) ) + return 1; + else + { + std::cout << + "XMLInterface::isValid() - XML File is invalid (in reference to schema " << + _schemaName << ")." << std::endl; + return 0; + } + } + else + { + std::cout << "XMLInterface::isValid() - Schema " << _schemaName << + " is invalid." << std::endl; + return 0; + } +#else // ifdef QT_USE_QTXMLPATTERNS + Q_UNUSED (fileName); + std::cout << + "XMLInterface: XML schema validation skipped. Qt 4.6 is required for validation." << + std::endl; + return 1; +#endif // QT_USE_QTXMLPATTERNS +} + +void XMLInterface::setSchema(const std::string &schemaName) +{ + _schemaName = schemaName; +} + + +int XMLInterface::insertStyleFileDefinition(const QString &fileName) const +{ + std::string path = fileName.toStdString(); + std::fstream stream(path.c_str()); + std::string line; + std::string styleDef("\n<?xml-stylesheet type=\"text/xsl\" href=\"OpenGeoSysGLI.xsl\"?>"); + + if (!stream.is_open()) + { + std::cout << "XMLInterface::insertStyleFileDefinition() - Could not open file...\n"; + return 0; + } + + stream.seekp(43 * sizeof(char),std::ios_base::beg); // go to the correct position in the stream + stream.write(styleDef.c_str(), 60 * sizeof(char)); // write new line with xml-stylesheet definition + stream.close(); + return 1; +} + +bool XMLInterface::checkHash(const QString &fileName) const +{ + QFileInfo fi(fileName); + QString md5FileName(fileName + ".md5"); + + std::ifstream md5( md5FileName.toStdString().c_str() ); + if (md5.is_open()) + { + char* md5HashStr = new char[16]; + md5.read(md5HashStr, 16); + QByteArray md5Hash(md5HashStr, 16); + delete[] md5HashStr; + if (hashIsGood(fileName, md5Hash)) + return true; + } + + if (!this->isValid(fileName)) + return false; + + std::cout << "File is valid, writing hashfile..." << std::endl; + QByteArray hash = calcHash(fileName); + std::ofstream out( md5FileName.toStdString().c_str(), std::ios::out ); + out.write(hash.data(), 16); + out.close(); + return true; +} + +bool XMLInterface::hashIsGood(const QString &fileName, const QByteArray &hash) const +{ + int hashLength = hash.length(); + QByteArray fileHash = calcHash(fileName); + if (fileHash.length() != hashLength) + return false; + for (int i = 0; i < hashLength; i++) + if (fileHash[i] != hash[i]) + { + std::cout << "Hashfile does not match data ... checking file ..." << + std::endl; + return false; + } + return true; +} + +QByteArray XMLInterface::calcHash(const QString &fileName) const +{ + std::ifstream is(fileName.toStdString().c_str(), std::ios::binary ); + is.seekg (0, std::ios::end); + int length = is.tellg(); + is.seekg (0, std::ios::beg); + char* buffer = new char [length]; + is.read (buffer,length); + is.close(); + + QByteArray hash = QCryptographicHash::hash(buffer, QCryptographicHash::Md5); + delete [] buffer; + return hash; +} + +} diff --git a/FileIO/XmlIO/XMLInterface.h b/FileIO/XmlIO/XMLInterface.h new file mode 100644 index 00000000000..09dc9082839 --- /dev/null +++ b/FileIO/XmlIO/XMLInterface.h @@ -0,0 +1,74 @@ +/** + * \file XMLInterface.h + * 18/02/2010 KR Initial implementation + */ + +#ifndef XMLINTERFACE_H +#define XMLINTERFACE_H + +#include "ProjectData.h" + +#include <QXmlStreamReader> +#include "Writer.h" + +class FEMCondition; + +class QFile; +class QDomDocument; +class QDomNode; +class QDomElement; + +namespace FileIO +{ + +/** + * \brief Base class for writing any information to and from XML files. + */ +class XMLInterface : public Writer +{ +public: + /** + * Constructor + * \param project Project data. + * \param schemaFile An XML schema file (*.xsd) that defines the structure of a valid data file. + */ + XMLInterface(ProjectData* project, const std::string &schemaFile); + + virtual ~XMLInterface() {}; + + /// As QXMLStreamWriter seems currently unable to include style-file links into xml-files, this method will workaround this issue and include the stylefile link. + int insertStyleFileDefinition(const QString &fileName) const; + + /// Check if the given xml-file is valid considering the schema-file used in the constructor + int isValid(const QString &fileName) const; + + void setNameForExport(std::string const& name) { _exportName = name; }; + + /// Sets the schema filename used to check if xml files are valid. + void setSchema(const std::string &schemaName); + + /// Reads an xml-file. + virtual int readFile(const QString &fileName) = 0; + +protected: + /// Checks if a hash for the given data file exists to skip the time-consuming validation part. + /// If a hash file exists _and_ the hash of the data file is the same as the content of the hash file the validation is skipped + /// If no hash file exists, the xml-file is validated and a hash file is written if the xml-file was valid. + bool checkHash(const QString &fileName) const; + + /// Calculates an MD5 hash of the given file. + QByteArray calcHash(const QString &fileName) const; + + /// Checks if the given file is conform to the given hash. + bool hashIsGood(const QString &fileName, const QByteArray &hash) const; + + ProjectData* _project; + + std::string _exportName; + std::string _schemaName; + std::map<size_t, size_t> _idx_map; +}; + +} + +#endif // XMLINTERFACE_H diff --git a/FileIO/XmlIO/XmlCndInterface.cpp b/FileIO/XmlIO/XmlCndInterface.cpp new file mode 100644 index 00000000000..1eeb989aec0 --- /dev/null +++ b/FileIO/XmlIO/XmlCndInterface.cpp @@ -0,0 +1,316 @@ +/** + * \file XmlCndInterface.cpp + * 2011/11/23 KR as derived class from XMLInterface + */ + +#include "XmlCndInterface.h" +#include "FEMCondition.h" + +#include <QFile> +#include <QTextCodec> +#include <QtXml/QDomDocument> + +#include <QStringList> +namespace FileIO +{ + +XmlCndInterface::XmlCndInterface(ProjectData* project, const std::string &schemaFile) +: XMLInterface(project, schemaFile), _type(FEMCondition::UNSPECIFIED) +{ +} + +int XmlCndInterface::readFile(std::vector<FEMCondition*> &conditions, const QString &fileName) +{ + QFile* file = new QFile(fileName); + if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) + { + std::cout << "XMLInterface::readFEMCondFile() - Can't open xml-file." << std::endl; + delete file; + return 0; + } + if (!checkHash(fileName)) + { + delete file; + return 0; + } + + QDomDocument doc("OGS-Cond-DOM"); + doc.setContent(file); + QDomElement docElement = doc.documentElement(); //root element, used for identifying file-type + if (docElement.nodeName().compare("OpenGeoSysCond")) + { + std::cout << "XMLInterface::readFEMCondFile() - Unexpected XML root." << std::endl; + delete file; + return 0; + } + + //std::vector<FEMCondition*> conditions; + QDomNodeList lists = docElement.childNodes(); + for (int i = 0; i < lists.count(); i++) + { + const QDomNode list_node (lists.at(i)); + if (list_node.nodeName().compare("BoundaryConditions") == 0) + readConditions(list_node, conditions, FEMCondition::BOUNDARY_CONDITION); + else if (list_node.nodeName().compare("InitialConditions") == 0) + readConditions(list_node, conditions, FEMCondition::INITIAL_CONDITION); + else if (list_node.nodeName().compare("SourceTerms") == 0) + readConditions(list_node, conditions, FEMCondition::SOURCE_TERM); + } + if (!conditions.empty()) + return 1; //do something like _geoObjects->addStationVec(stations, stnName, color); + else + { + std::cout << "XMLInterface::readFEMCondFile() - No FEM Conditions found..." << + std::endl; + return 0; + } + + delete file; + + return 1; +} + +void XmlCndInterface::readConditions( const QDomNode &listRoot, + std::vector<FEMCondition*> &conditions, + FEMCondition::CondType type) +{ + QDomElement cond = listRoot.firstChildElement(); + while (!cond.isNull()) + { + std::string geometry_name ( cond.attribute("geometry").toStdString() ); + if (this->_project->getGEOObjects()->exists(geometry_name) >= 0 || + this->_project->meshExists(geometry_name)) + { + + FEMCondition* c ( new FEMCondition(geometry_name, type) ); + + QDomNodeList condProperties = cond.childNodes(); + for (int i = 0; i < condProperties.count(); i++) + { + const QDomNode prop_node (condProperties.at(i)); + if (condProperties.at(i).nodeName().compare("Process") == 0) + { + QDomNodeList processProps = prop_node.childNodes(); + for (int j = 0; j < processProps.count(); j++) + { + const QString prop_name(processProps.at(j).nodeName()); + if (prop_name.compare("Type") == 0) + c->setProcessType(FiniteElement::convertProcessType(processProps.at(j).toElement().text().toStdString())); + else if (prop_name.compare("Variable") == 0) + c->setProcessPrimaryVariable(FiniteElement::convertPrimaryVariable(processProps.at(j).toElement().text().toStdString())); + } + } + else if (prop_node.nodeName().compare("Geometry") == 0) + { + QDomNodeList geoProps = prop_node.childNodes(); + for (int j = 0; j < geoProps.count(); j++) + { + const QString prop_name(geoProps.at(j).nodeName()); + if (prop_name.compare("Type") == 0) + c->setGeoType(GeoLib::convertGeoType(geoProps.at(j).toElement().text().toStdString())); + else if (prop_name.compare("Name") == 0) + c->setGeoName(geoProps.at(j).toElement().text().toStdString()); + } + } + else if (prop_node.nodeName().compare("Distribution") == 0) + { + QDomNodeList distProps = prop_node.childNodes(); + for (int j = 0; j < distProps.count(); j++) + { + const QString prop_name(distProps.at(j).nodeName()); + if (prop_name.compare("Type") == 0) + c->setProcessDistributionType(FiniteElement::convertDisType(distProps.at(j).toElement().text().toStdString())); + else if (prop_name.compare("Value") == 0) + { + std::vector<size_t> disNodes; + std::vector<double> disValues; + if (c->getProcessDistributionType()==FiniteElement::CONSTANT || + c->getProcessDistributionType()==FiniteElement::CONSTANT_NEUMANN) + disValues.push_back( strtod(distProps.at(j).toElement().text().toStdString().c_str(), 0) ); + else if (c->getProcessDistributionType()==FiniteElement::LINEAR || + c->getProcessDistributionType()==FiniteElement::LINEAR_NEUMANN || + c->getProcessDistributionType()==FiniteElement::DIRECT) + { + QString text = distProps.at(j).toElement().text(); + QStringList list = text.split(QRegExp("\\t")); + size_t count(0); + for (QStringList::iterator it=list.begin(); it!=list.end(); ++it) + { + std::string val (it->trimmed().toStdString()); + if (!val.empty()) + { + if (count%2==0) + disNodes.push_back(atoi(val.c_str())); + else + disValues.push_back(strtod(val.c_str(), 0)); + count++; + } + } + } + else + std::cout << "Error in XmlCndInterface::readConditions() - Distribution type not supported." << std::endl; + c->setDisValues(disNodes, disValues); + } + } + } + } + conditions.push_back(c); + } + else + { + std::cout << "Error loading FEM Conditions: No geometry \"" << geometry_name << "\" found." << std::endl; + } + cond = cond.nextSiblingElement(); + } +} + +int XmlCndInterface::write(std::ostream& stream) +{ + stream << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"; // xml definition + stream << "<?xml-stylesheet type=\"text/xsl\" href=\"OpenGeoSysCND.xsl\"?>\n\n"; // stylefile definition + + QDomDocument doc("OGS-CND-DOM"); + QDomElement root = doc.createElement("OpenGeoSysCond"); + root.setAttribute( "xmlns:ogs", "http://www.opengeosys.net" ); + root.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" ); + root.setAttribute( "xsi:noNamespaceSchemaLocation", "http://141.65.34.25/OpenGeoSysCND.xsd" ); + + const std::vector<FEMCondition*> conditions (_project->getConditions(FiniteElement::INVALID_PROCESS, _exportName, _type) ); + + if (conditions.empty()) return 1; + + doc.appendChild(root); + + + size_t nConditions (conditions.size()); + for (size_t i=0; i<nConditions; i++) + { + FEMCondition::CondType current_type = conditions[i]->getCondType(); + if (current_type == _type || _type == FEMCondition::UNSPECIFIED) + { + QDomElement listTag; + QString condText; + + if (current_type == FEMCondition::BOUNDARY_CONDITION) + { + listTag = this->getCondListElement(doc, root, "BoundaryConditions"); + condText = "BC"; + } + else if (current_type == FEMCondition::INITIAL_CONDITION) + { + listTag = this->getCondListElement(doc, root, "InitialConditions"); + condText = "IC"; + } + else if (current_type == FEMCondition::SOURCE_TERM) + { + listTag = this->getCondListElement(doc, root, "SourceTerms"); + condText = "ST"; + } + else + { + std::cout << "Error in XmlCndInterface::writeFile() - Unspecified FEMConditions found ... Abort writing." << std::endl; + return 0; + } + this->writeCondition(doc, listTag, conditions[i], condText, QString::fromStdString(_exportName)); + } + } + std::string xml = doc.toString().toStdString(); + stream << xml; + + return 1; +} + +void XmlCndInterface::writeCondition( QDomDocument doc, QDomElement &listTag, const FEMCondition* cond, const QString &condText, const QString &geometryName) const +{ + QString geoName (QString::fromStdString(cond->getAssociatedGeometryName())); + + if ((geometryName.length()>0) && (geoName.compare(geometryName) != 0)) + { + std::cout << "Geometry name not matching, skipping condition \"" << cond->getGeoName() << "\"..." << std::endl; + return; + } + + QDomElement condTag ( doc.createElement(condText) ); + condTag.setAttribute("geometry", geoName); + listTag.appendChild(condTag); + + QDomElement processTag ( doc.createElement("Process") ); + condTag.appendChild(processTag); + QDomElement processTypeTag ( doc.createElement("Type") ); + processTag.appendChild(processTypeTag); + QDomText processTypeText ( doc.createTextNode( + QString::fromStdString(FiniteElement::convertProcessTypeToString(cond->getProcessType()))) ); + processTypeTag.appendChild(processTypeText); + QDomElement processPVTag ( doc.createElement("Variable") ); + processTag.appendChild(processPVTag); + QDomText processPVText ( doc.createTextNode( + QString::fromStdString(FiniteElement::convertPrimaryVariableToString(cond->getProcessPrimaryVariable()))) ); + processPVTag.appendChild(processPVText); + + QDomElement geoTag ( doc.createElement("Geometry") ); + condTag.appendChild(geoTag); + QDomElement geoTypeTag ( doc.createElement("Type") ); + geoTag.appendChild(geoTypeTag); + QDomText geoTypeText ( doc.createTextNode( + QString::fromStdString(GeoLib::convertGeoTypeToString(cond->getGeoType()))) ); + geoTypeTag.appendChild(geoTypeText); + QDomElement geoNameTag ( doc.createElement("Name") ); + geoTag.appendChild(geoNameTag); + QString geo_obj_name ( QString::fromStdString(cond->getGeoName()) ); + QDomText geoNameText ( doc.createTextNode(geo_obj_name) ); + geoNameTag.appendChild(geoNameText); + + QDomElement disTag ( doc.createElement("Distribution") ); + condTag.appendChild(disTag); + QDomElement disTypeTag ( doc.createElement("Type") ); + disTag.appendChild(disTypeTag); + QDomText disTypeText ( doc.createTextNode( + QString::fromStdString(FiniteElement::convertDisTypeToString(cond->getProcessDistributionType()))) ); + disTypeTag.appendChild(disTypeText); + QDomElement disValueTag ( doc.createElement("Value") ); + disTag.appendChild(disValueTag); + /* + if (cond->getProcessDistributionType() != FiniteElement::DIRECT) + { + double dis_value (cond->getDisValue()[0]); //TODO: do this correctly! + disValueText = doc.createTextNode(QString::number(dis_value)); + } + else + disValueText = doc.createTextNode(QString::fromStdString(cond->getDirectFileName())); + */ + const std::vector<size_t> dis_nodes = cond->getDisNodes(); + const std::vector<double> dis_values = cond->getDisValues(); + const size_t nNodes = dis_nodes.size(); + const size_t nValues = dis_values.size(); + std::stringstream ss; + if (nNodes==0 && nValues==1) // CONSTANT + ss << dis_values[0]; + else if ((nValues>0) && (nValues==nNodes)) // LINEAR && DIRECT + { + ss << "\n\t"; + for (size_t i=0; i<nValues; i++) + ss << dis_nodes[i] << "\t" << dis_values[i] << "\n\t"; + } + else + { + std::cout << "Error in XmlCndInterface::writeCondition() - Inconsistent length of distribution value array." << std::endl; + ss << "-9999"; + } + std::string dv = ss.str(); + QDomText disValueText = doc.createTextNode(QString::fromStdString(ss.str())); + disValueTag.appendChild(disValueText); +} + +QDomElement XmlCndInterface::getCondListElement( QDomDocument doc, QDomElement &root, const QString &text ) const +{ + QDomNodeList list = root.elementsByTagName(text); + if (list.isEmpty()) + { + QDomElement newListTag ( doc.createElement(text) ); + root.appendChild(newListTag); + return newListTag; + } + return list.at(0).toElement(); +} + +} diff --git a/FileIO/XmlIO/XmlCndInterface.h b/FileIO/XmlIO/XmlCndInterface.h new file mode 100644 index 00000000000..005539e0e1a --- /dev/null +++ b/FileIO/XmlIO/XmlCndInterface.h @@ -0,0 +1,62 @@ +/** + * \file XmlCndInterface.h + * 2011/11/23 KR as derived class from XMLInterface + */ + +#ifndef XMLCNDINTERFACE_H +#define XMLCNDINTERFACE_H + +#include "XMLInterface.h" + +class FEMCondition; + +namespace FileIO +{ + +/** + * \brief Reads and writes FEM Conditions to and from XML files. + */ +class XmlCndInterface : public XMLInterface +{ +public: + /** + * Constructor + * \param project Project data. + * \param schemaFile An XML schema file (*.xsd) that defines the structure of a valid data file. + */ + XmlCndInterface(ProjectData* project, const std::string &schemaFile); + + ~XmlCndInterface() {}; + + /// Dummy function so class hierarchy works. This needs to be implemented later. + int readFile(const QString &fileName) + { + Q_UNUSED(fileName) + std::cout << "There is currently no implementation for XmlCndInterface::readFile(const QString&)." << std::endl; + return 0; + } + + /// Reads an xml-file containing FEM Conditions such as Boundary- or Initial Conditions + int readFile(std::vector<FEMCondition*> &conditions, const QString &fileName); + + void setConditionType(FEMCondition::CondType type) { _type = type; }; + + +protected: + int write(std::ostream& stream); + +private: + /// Read the details of various FEM Conditions from an xml-file + void readConditions( const QDomNode &condRoot, + std::vector<FEMCondition*> &conditions, + FEMCondition::CondType type); + + QDomElement getCondListElement( QDomDocument doc, QDomElement &root, const QString &condText ) const; + void writeCondition( QDomDocument doc, QDomElement &listTag, const FEMCondition* cond, const QString &condText, const QString &geoName ) const; + + FEMCondition::CondType _type; +}; + +} + +#endif // XMLCNDINTERFACE_H diff --git a/FileIO/XmlIO/XmlGmlInterface.cpp b/FileIO/XmlIO/XmlGmlInterface.cpp new file mode 100644 index 00000000000..929135dd8b5 --- /dev/null +++ b/FileIO/XmlIO/XmlGmlInterface.cpp @@ -0,0 +1,382 @@ +/** + * \file XmlGmlInterface.cpp + * 2011/11/23 KR as derived class from XMLInterface + */ + +#include "XmlGmlInterface.h" + +#include <QFile> +#include <QTextCodec> +#include <QtXml/QDomDocument> + +namespace FileIO +{ + +XmlGmlInterface::XmlGmlInterface(ProjectData* project, const std::string &schemaFile) +: XMLInterface(project, schemaFile) +{ +} + +int XmlGmlInterface::readFile(const QString &fileName) +{ + GeoLib::GEOObjects* geoObjects = _project->getGEOObjects(); + std::string gliName("[NN]"); + + QFile* file = new QFile(fileName); + if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) + { + std::cout << "XmlGmlInterface::readFile() - Can't open xml-file " << + fileName.toStdString() << "." << std::endl; + delete file; + return 0; + } + if (!checkHash(fileName)) + { + delete file; + return 0; + } + + std::vector<GeoLib::Point*>* points = new std::vector<GeoLib::Point*>; + std::vector<GeoLib::Polyline*>* polylines = new std::vector<GeoLib::Polyline*>; + std::vector<GeoLib::Surface*>* surfaces = new std::vector<GeoLib::Surface*>; + + std::map<std::string, size_t>* pnt_names = new std::map<std::string, size_t>; + std::map<std::string, size_t>* ply_names = new std::map<std::string, size_t>; + std::map<std::string, size_t>* sfc_names = new std::map<std::string, size_t>; + + QDomDocument doc("OGS-GLI-DOM"); + doc.setContent(file); + QDomElement docElement = doc.documentElement(); //OpenGeoSysGLI + if (docElement.nodeName().compare("OpenGeoSysGLI")) + { + std::cout << "XmlGmlInterface::readFile() - Unexpected XML root." << std::endl; + delete file; + return 0; + } + + QDomNodeList geoTypes = docElement.childNodes(); + + for (int i = 0; i < geoTypes.count(); i++) + { + const QDomNode type_node(geoTypes.at(i)); + if (type_node.nodeName().compare("name") == 0) + gliName = type_node.toElement().text().toStdString(); + else if (type_node.nodeName().compare("points") == 0) + { + readPoints(type_node, points, pnt_names); + geoObjects->addPointVec(points, gliName, pnt_names); + } + else if (type_node.nodeName().compare("polylines") == 0) + readPolylines(type_node, polylines, points, + geoObjects->getPointVecObj(gliName)->getIDMap(), ply_names); + else if (type_node.nodeName().compare("surfaces") == 0) + readSurfaces(type_node, surfaces, points, + geoObjects->getPointVecObj(gliName)->getIDMap(), sfc_names); + else + std::cout << "Unknown XML-Node found in file." << std::endl; + } + delete file; + + if (!polylines->empty()) + geoObjects->addPolylineVec(polylines, gliName, ply_names); + if (!surfaces->empty()) + geoObjects->addSurfaceVec(surfaces, gliName, sfc_names); + return 1; +} + +void XmlGmlInterface::readPoints( const QDomNode &pointsRoot, + std::vector<GeoLib::Point*>* points, + std::map<std::string, size_t>* pnt_names ) +{ + char* pEnd; + QDomElement point = pointsRoot.firstChildElement(); + while (!point.isNull()) + { + if (point.hasAttribute("id") && point.hasAttribute("x") && point.hasAttribute("y")) + { + _idx_map.insert (std::pair<size_t, + size_t>(strtol((point.attribute("id")). + toStdString().c_str(), &pEnd, + 10), points->size())); + double zVal = (point.hasAttribute("z")) ? strtod((point.attribute( + "z")).toStdString( + ).c_str(), + 0) : 0.0; + GeoLib::Point* p = new GeoLib::Point(strtod((point.attribute("x")).toStdString().c_str(), + 0), + strtod((point.attribute("y")). + toStdString().c_str(), 0), + zVal); + if (point.hasAttribute("name")) + pnt_names->insert( std::pair<std::string, + size_t>(point.attribute("name"). + toStdString(), points->size()) ); + points->push_back(p); + } + else + std::cout << + "XmlGmlInterface::readPoints() - Attribute missing in <point> tag ..." << + std::endl; + + point = point.nextSiblingElement(); + } + if (pnt_names->empty()) + pnt_names = NULL; // if names-map is empty, set it to NULL because it is not needed +} + +void XmlGmlInterface::readPolylines( const QDomNode &polylinesRoot, + std::vector<GeoLib::Polyline*>* polylines, + std::vector<GeoLib::Point*>* points, + const std::vector<size_t> &pnt_id_map, + std::map<std::string, size_t>* ply_names ) +{ + size_t idx(0); + QDomElement polyline = polylinesRoot.firstChildElement(); + while (!polyline.isNull()) + { + if (polyline.hasAttribute("id")) + { + idx = polylines->size(); + polylines->push_back(new GeoLib::Polyline(*points)); + + if (polyline.hasAttribute("name")) + ply_names->insert( std::pair<std::string, + size_t>(polyline.attribute("name"). + toStdString(), idx) ); + + QDomElement point = polyline.firstChildElement(); + while (!point.isNull()) + { + (*polylines)[idx]->addPoint(pnt_id_map[_idx_map[atoi(point.text(). + toStdString(). + c_str())]]); + point = point.nextSiblingElement(); + } + } + else + std::cout << + "XmlGmlInterface::readPolylines() - Attribute missing in <polyline> tag ..." + << + std::endl; + + polyline = polyline.nextSiblingElement(); + } + if (ply_names->empty()) + ply_names = NULL; // if names-map is empty, set it to NULL because it is not needed +} + +void XmlGmlInterface::readSurfaces( const QDomNode &surfacesRoot, + std::vector<GeoLib::Surface*>* surfaces, + std::vector<GeoLib::Point*>* points, + const std::vector<size_t> &pnt_id_map, + std::map<std::string, size_t>* sfc_names ) +{ + QDomElement surface = surfacesRoot.firstChildElement(); + while (!surface.isNull()) + { + if (surface.hasAttribute("id")) + { + surfaces->push_back(new GeoLib::Surface(*points)); + + if (surface.hasAttribute("name")) + sfc_names->insert( std::pair<std::string, + size_t>(surface.attribute("name"). + toStdString(), + surfaces->size() - + 1) ); + + QDomElement element = surface.firstChildElement(); + while (!element.isNull()) + { + if (element.hasAttribute("p1") && element.hasAttribute("p2") && + element.hasAttribute("p3")) + { + size_t p1 = + pnt_id_map[_idx_map[atoi((element.attribute("p1")). + toStdString().c_str())]]; + size_t p2 = + pnt_id_map[_idx_map[atoi((element.attribute("p2")). + toStdString().c_str())]]; + size_t p3 = + pnt_id_map[_idx_map[atoi((element.attribute("p3")). + toStdString().c_str())]]; + surfaces->back()->addTriangle(p1,p2,p3); + } + else + std::cout << + "XmlGmlInterface::readSurfaces() - Attribute missing in <element> tag ..." + << std::endl; + element = element.nextSiblingElement(); + } + } + else + std::cout << + "XmlGmlInterface::readSurfaces() - Attribute missing in <surface> tag ..." << + std::endl; + + surface = surface.nextSiblingElement(); + } + if (sfc_names->empty()) + sfc_names = NULL; // if names-map is empty, set it to NULL because it is not needed +} + +int XmlGmlInterface::write(std::ostream& stream) +{ + if (this->_exportName.empty()) + { + std::cout << "Error in XmlGmlInterface::write() - No geometry specified..." << std::endl; + return 0; + } + + GeoLib::GEOObjects* geoObjects = _project->getGEOObjects(); + size_t nPoints = 0, nPolylines = 0, nSurfaces = 0; + + stream << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"; // xml definition + stream << "<?xml-stylesheet type=\"text/xsl\" href=\"OpenGeoSysGLI.xsl\"?>\n\n"; // stylefile definition + + QDomDocument doc("OGS-GML-DOM"); + QDomElement root = doc.createElement("OpenGeoSysGLI"); + root.setAttribute( "xmlns:ogs", "http://www.opengeosys.net" ); + root.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" ); + root.setAttribute( "xsi:noNamespaceSchemaLocation", "http://141.65.34.25/OpenGeoSysCND.xsd" ); + + doc.appendChild(root); + + QDomElement geoNameTag = doc.createElement("name"); + root.appendChild(geoNameTag); + QDomText geoNameText = doc.createTextNode(QString::fromStdString(_exportName)); + geoNameTag.appendChild(geoNameText); + + // POINTS + QDomElement pointsListTag = doc.createElement("points"); + root.appendChild(pointsListTag); + + const GeoLib::PointVec* pnt_vec (geoObjects->getPointVecObj(_exportName)); + if (pnt_vec) + { + const std::vector<GeoLib::Point*>* points (pnt_vec->getVector()); + + if (!points->empty()) + { + nPoints = points->size(); + for (size_t i = 0; i < nPoints; i++) + { + QDomElement pointTag = doc.createElement("point"); + pointTag.setAttribute("id", QString::number(i)); + pointTag.setAttribute("x", QString::number((*(*points)[i])[0], 'f')); + pointTag.setAttribute("y", QString::number((*(*points)[i])[1], 'f')); + pointTag.setAttribute("z", QString::number((*(*points)[i])[2], 'f')); + + std::string point_name; + if (pnt_vec->getNameOfElementByID(i, point_name)) + pointTag.setAttribute("name", QString::fromStdString(point_name)); + + pointsListTag.appendChild(pointTag); + } + } + else + { + std::cout << "Point vector empty, abort writing geometry." << std::endl; + return 0; + } + } + else + { + std::cout << "Point vector empty, abort writing geometry." << std::endl; + return 0; + } + + // POLYLINES + const GeoLib::PolylineVec* ply_vec (geoObjects->getPolylineVecObj(_exportName)); + if (ply_vec) + { + const std::vector<GeoLib::Polyline*>* polylines (ply_vec->getVector()); + + if (polylines) + { + if (!polylines->empty()) + { + QDomElement plyListTag = doc.createElement("polylines"); + root.appendChild(plyListTag); + nPolylines = polylines->size(); + for (size_t i = 0; i < nPolylines; i++) + { + QDomElement polylineTag = doc.createElement("polyline"); + polylineTag.setAttribute("id", QString::number(i)); + + std::string ply_name(""); + if (ply_vec->getNameOfElementByID(i, ply_name)) + polylineTag.setAttribute("name", QString::fromStdString(ply_name)); + + plyListTag.appendChild(polylineTag); + + nPoints = (*polylines)[i]->getNumberOfPoints(); + for (size_t j = 0; j < nPoints; j++) + { + QDomElement plyPointTag = doc.createElement("pnt"); + polylineTag.appendChild(plyPointTag); + QDomText plyPointText = doc.createTextNode(QString::number(((*polylines)[i])->getPointID(j))); + plyPointTag.appendChild(plyPointText); + } + } + } + else + std::cout << "Polyline vector empty, no polylines written to file." << std::endl; + } + } + else + std::cout << "Polyline vector empty, no polylines written to file." << std::endl; + + + // SURFACES + const GeoLib::SurfaceVec* sfc_vec (geoObjects->getSurfaceVecObj(_exportName)); + if (sfc_vec) + { + const std::vector<GeoLib::Surface*>* surfaces (sfc_vec->getVector()); + + if (surfaces) + { + if (! surfaces->empty()) + { + QDomElement sfcListTag = doc.createElement("surfaces"); + root.appendChild(sfcListTag); + nSurfaces = surfaces->size(); + for (size_t i = 0; i < nSurfaces; i++) + { + QDomElement surfaceTag = doc.createElement("surface"); + surfaceTag.setAttribute("id", QString::number(i)); + + std::string sfc_name(""); + if (sfc_vec->getNameOfElementByID(i, sfc_name)) + surfaceTag.setAttribute("name", QString::fromStdString(sfc_name)); + + sfcListTag.appendChild(surfaceTag); + + // writing the elements compromising the surface + size_t nElements = ((*surfaces)[i])->getNTriangles(); + for (size_t j = 0; j < nElements; j++) + { + QDomElement elementTag = doc.createElement("element"); + elementTag.setAttribute("p1", QString::number((*(*(*surfaces)[i])[j])[0])); + elementTag.setAttribute("p2", QString::number((*(*(*surfaces)[i])[j])[1])); + elementTag.setAttribute("p3", QString::number((*(*(*surfaces)[i])[j])[2])); + surfaceTag.appendChild(elementTag); + } + } + } + else + std::cout << "Surface vector empty, no surfaces written to file." << std::endl; + } + } + else + std::cout << "Surface vector empty, no surfaces written to file." << std::endl; + + + //insertStyleFileDefinition(filename); + std::string xml = doc.toString().toStdString(); + stream << xml; + + return 1; +} + +} diff --git a/FileIO/XmlIO/XmlGmlInterface.h b/FileIO/XmlIO/XmlGmlInterface.h new file mode 100644 index 00000000000..2fb9b3318a8 --- /dev/null +++ b/FileIO/XmlIO/XmlGmlInterface.h @@ -0,0 +1,59 @@ +/** + * \file XmlGmlInterface.h + * 2011/11/23 KR as derived class from XMLInterface + */ + +#ifndef XMLGMLINTERFACE_H +#define XMLGMLINTERFACE_H + +#include "XMLInterface.h" + +namespace FileIO +{ + +/** + * \brief Reads and writes GeoObjects to and from XML files. + */ +class XmlGmlInterface : public XMLInterface +{ +public: + /** + * Constructor + * \param project Project data. + * \param schemaFile An XML schema file (*.xsd) that defines the structure of a valid data file. + */ + XmlGmlInterface(ProjectData* project, const std::string &schemaFile); + + virtual ~XmlGmlInterface() {}; + + /// Reads an xml-file containing geometric object definitions into the GEOObjects used in the contructor + int readFile(const QString &fileName); + +protected: + int write(std::ostream& stream); + +private: + /// Reads GeoLib::Point-objects from an xml-file + void readPoints ( const QDomNode &pointsRoot, + std::vector<GeoLib::Point*>* points, + std::map<std::string, size_t>* pnt_names ); + + /// Reads GeoLib::Polyline-objects from an xml-file + void readPolylines ( const QDomNode &polylinesRoot, + std::vector<GeoLib::Polyline*>* polylines, + std::vector<GeoLib::Point*>* points, + const std::vector<size_t> &pnt_id_map, + std::map<std::string, size_t>* ply_names ); + + /// Reads GeoLib::Surface-objects from an xml-file + void readSurfaces ( const QDomNode &surfacesRoot, + std::vector<GeoLib::Surface*>* surfaces, + std::vector<GeoLib::Point*>* points, + const std::vector<size_t> &pnt_id_map, + std::map<std::string, size_t>* sfc_names ); + +}; + +} + +#endif // XMLGMLINTERFACE_H diff --git a/FileIO/XmlIO/XmlGspInterface.cpp b/FileIO/XmlIO/XmlGspInterface.cpp new file mode 100644 index 00000000000..0b976a961cd --- /dev/null +++ b/FileIO/XmlIO/XmlGspInterface.cpp @@ -0,0 +1,199 @@ +/** + * \file XmlGspInterface.cpp + * 2011/11/23 KR as derived class from XMLInterface + */ + +#include "XmlGspInterface.h" + +#include "XmlGmlInterface.h" +#include "XmlStnInterface.h" +#include "XmlCndInterface.h" + +#include "MeshIO.h" + +#include <QFileInfo> +#include <QFile> +#include <QtXml/QDomDocument> + +namespace FileIO +{ + +XmlGspInterface::XmlGspInterface(ProjectData* project, const std::string &schemaFile) +: XMLInterface(project, schemaFile) +{ +} + +int XmlGspInterface::readFile(const QString &fileName) +{ + QFile* file = new QFile(fileName); + QFileInfo fi(fileName); + QString path = (fi.path().length() > 3) ? QString(fi.path() + "/") : fi.path(); + + QFileInfo si(QString::fromStdString(_schemaName)); + QString schemaPath(si.absolutePath() + "/"); + + if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) + { + std::cout << "XmlGspInterface::readFile() - Can't open xml-file " << + fileName.toStdString() << "." << std::endl; + delete file; + return 0; + } + if (!checkHash(fileName)) + { + delete file; + return 0; + } + + QDomDocument doc("OGS-PROJECT-DOM"); + doc.setContent(file); + QDomElement docElement = doc.documentElement(); //OpenGeoSysProject + if (docElement.nodeName().compare("OpenGeoSysProject")) + { + std::cout << "XmlGspInterface::readFile() - Unexpected XML root." << std::endl; + delete file; + return 0; + } + + QDomNodeList fileList = docElement.childNodes(); + + for(int i = 0; i < fileList.count(); i++) + { + const QString file_node(fileList.at(i).nodeName()); + if (file_node.compare("geo") == 0) + { + XmlGmlInterface gml(_project, schemaPath.toStdString() + "OpenGeoSysGLI.xsd"); + const QDomNodeList childList = fileList.at(i).childNodes(); + for(int j = 0; j < childList.count(); j++) + { + const QDomNode child_node (childList.at(j)); + if (child_node.nodeName().compare("file") == 0) + { + std::cout << "path: " << path.toStdString() << "#" << std::endl; + std::cout << "file name: " << (child_node.toElement().text()).toStdString() << "#" << std::endl; + gml.readFile(QString(path + child_node.toElement().text())); + } + } + } + else if (file_node.compare("stn") == 0) + { + XmlStnInterface stn(_project, schemaPath.toStdString() + "OpenGeoSysSTN.xsd"); + const QDomNodeList childList = fileList.at(i).childNodes(); + for(int j = 0; j < childList.count(); j++) + if (childList.at(j).nodeName().compare("file") == 0) + stn.readFile(QString(path + childList.at(j).toElement().text())); + } + else if (file_node.compare("msh") == 0) + { + const std::string msh_name = path.toStdString() + + fileList.at(i).toElement().text().toStdString(); + FileIO::MeshIO meshIO; + MeshLib::Mesh* msh = meshIO.loadMeshFromFile(msh_name); + QFileInfo fi(QString::fromStdString(msh_name)); + std::string name = fi.fileName().toStdString(); + _project->addMesh(msh, name); + //GridAdapter msh(fileList.at(i).toElement().text().toStdString()); + // TODO gridadapter to mesh-models + } + } + + return 1; +} + +int XmlGspInterface::writeToFile(std::string filename) +{ + _filename = filename; + return FileIO::Writer::writeToFile(filename); +} + +int XmlGspInterface::write(std::ostream& stream) +{ + GeoLib::GEOObjects* geoObjects = _project->getGEOObjects(); + QFileInfo fi(QString::fromStdString(_filename)); + std::string path((fi.absolutePath()).toStdString() + "/"); + + stream << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"; // xml definition + stream << "<?xml-stylesheet type=\"text/xsl\" href=\"OpenGeoSysProject.xsl\"?>\n\n"; // stylefile definition + + QDomDocument doc("OGS-PROJECT-DOM"); + QDomElement root = doc.createElement("OpenGeoSysProject"); + root.setAttribute( "xmlns:ogs", "http://www.opengeosys.net" ); + root.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" ); + root.setAttribute( "xsi:noNamespaceSchemaLocation", + "http://141.65.34.25/OpenGeoSysProject.xsd" ); + + doc.appendChild(root); + + // GLI + std::vector<std::string> geoNames; + geoObjects->getGeometryNames(geoNames); + for (std::vector<std::string>::const_iterator it(geoNames.begin()); it != geoNames.end(); + ++it) + { + // write GLI file + XmlGmlInterface gml(_project, path + "OpenGeoSysGLI.xsd"); + std::string name(*it); + gml.setNameForExport(name); + if (gml.writeToFile(std::string(path + name + ".gml"))) + { + // write entry in project file + QDomElement geoTag = doc.createElement("geo"); + root.appendChild(geoTag); + QDomElement fileNameTag = doc.createElement("file"); + geoTag.appendChild(fileNameTag); + QDomText fileNameText = doc.createTextNode(QString::fromStdString(name + ".gml")); + fileNameTag.appendChild(fileNameText); + } + } + + // MSH + const std::map<std::string, MeshLib::Mesh*> msh_vec = _project->getMeshObjects(); + for (std::map<std::string, MeshLib::Mesh*>::const_iterator it(msh_vec.begin()); + it != msh_vec.end(); ++it) + { + // write mesh file + std::string fileName(path + it->first); + FileIO::MeshIO meshIO; + meshIO.setMesh(it->second); + meshIO.writeToFile(fileName); + + // write entry in project file + QDomElement mshTag = doc.createElement("msh"); + root.appendChild(mshTag); + QDomElement fileNameTag = doc.createElement("file"); + mshTag.appendChild(fileNameTag); + QDomText fileNameText = doc.createTextNode(QString::fromStdString(it->first)); + fileNameTag.appendChild(fileNameText); + } + + // STN + std::vector<std::string> stnNames; + geoObjects->getStationVectorNames(stnNames); + for (std::vector<std::string>::const_iterator it(stnNames.begin()); it != stnNames.end(); + ++it) + { + // write STN file + XmlStnInterface stn(_project, path + "OpenGeoSysSTN.xsd"); + std::string name(*it); + stn.setNameForExport(name); + + if (stn.writeToFile(path + name + ".stn")) + { + // write entry in project file + QDomElement geoTag = doc.createElement("stn"); + root.appendChild(geoTag); + QDomElement fileNameTag = doc.createElement("file"); + geoTag.appendChild(fileNameTag); + QDomText fileNameText = doc.createTextNode(QString::fromStdString(name + ".stn")); + fileNameTag.appendChild(fileNameText); + } + else + std::cout << "XmlGspInterface::writeFile() - Error writing file: " << name << std::endl; + } + + std::string xml = doc.toString().toStdString(); + stream << xml; + return 1; +} + +} diff --git a/FileIO/XmlIO/XmlGspInterface.h b/FileIO/XmlIO/XmlGspInterface.h new file mode 100644 index 00000000000..1524941655d --- /dev/null +++ b/FileIO/XmlIO/XmlGspInterface.h @@ -0,0 +1,44 @@ +/** + * \file XmlGspInterface.h + * 2011/11/23 KR as derived class from XMLInterface + */ + +#ifndef XMLGSPINTERFACE_H +#define XMLGSPINTERFACE_H + +#include "XMLInterface.h" + +namespace FileIO +{ + +/** + * \brief Reads and writes project information to and from XML files. + */ +class XmlGspInterface : public XMLInterface +{ +public: + /** + * Constructor + * \param project Project data. + * \param schemaFile An XML schema file (*.xsd) that defines the structure of a valid data file. + */ + XmlGspInterface(ProjectData* project, const std::string &schemaFile); + + virtual ~XmlGspInterface() {}; + + /// Reads an xml-file containing a GeoSys project. + /// Project files currently cover only geo-, msh- and station-data. This will be expanded in the future. + int readFile(const QString &fileName); + + int writeToFile(std::string filename); + +protected: + int write(std::ostream& stream); + +private: + std::string _filename; +}; + +} + +#endif // XMLGSPINTERFACE_H diff --git a/FileIO/XmlIO/XmlLutReader.h b/FileIO/XmlIO/XmlLutReader.h new file mode 100644 index 00000000000..f46de52116a --- /dev/null +++ b/FileIO/XmlIO/XmlLutReader.h @@ -0,0 +1,92 @@ +/** + * \file XmlLutReader.h + * 2011/01/30 KR Initial implementation + */ + +#ifndef XMLLUTREADER_H +#define XMLLUTREADER_H + +#include "VtkColorLookupTable.h" + +#include <QFile> +#include <QtXml/QDomDocument> + +#include <iostream> + +/** + * \brief Reader for vtk-Lookup-Tables (in XML / ParaView Format) + */ +class XmlLutReader +{ +public: + static VtkColorLookupTable* readFromFile(const QString &fileName) + { + VtkColorLookupTable* lut = VtkColorLookupTable::New(); + + QFile* file = new QFile(fileName); + if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) + { + std::cout << "XmlLutReader::readFromFile() - Can't open xml-file." << std::endl; + delete file; + return NULL; + } + + QDomDocument doc("ColorMap"); + doc.setContent(file); + QDomElement docElement = doc.documentElement(); + if (docElement.nodeName().compare("ColorMap")) + { + std::cout << "XmlLutReader::readFromFile() - Unexpected XML root." << std::endl; + delete file; + return NULL; + } + + if (docElement.hasAttribute("interpolation")) + { + if (docElement.attribute("interpolation").compare("Linear") == 0) + lut->setInterpolationType(VtkColorLookupTable::LINEAR); + else if (docElement.attribute("interpolation").compare("Exponential") == 0) + lut->setInterpolationType(VtkColorLookupTable::EXPONENTIAL); + else + lut->setInterpolationType(VtkColorLookupTable::NONE); + } + else // default + lut->setInterpolationType(VtkColorLookupTable::NONE); + + QDomElement point = docElement.firstChildElement(); + double range[2] = { strtod((point.attribute("x")).toStdString().c_str(),0), strtod((point.attribute("x")).toStdString().c_str(),0) }; + + while (!point.isNull()) + { + if ((point.nodeName().compare("Point") == 0 ) + && point.hasAttribute("x") + && point.hasAttribute("r") + && point.hasAttribute("g") + && point.hasAttribute("b")) + { + double value = strtod((point.attribute("x")).toStdString().c_str(),0); + char r = static_cast<int>(255 * strtod((point.attribute("r")).toStdString().c_str(),0)); + char g = static_cast<int>(255 * strtod((point.attribute("g")).toStdString().c_str(),0)); + char b = static_cast<int>(255 * strtod((point.attribute("b")).toStdString().c_str(),0)); + char o = static_cast<int>(255 * (point.hasAttribute("o") ? strtod((point.attribute("o")).toStdString().c_str(),0) : 1)); + + if (value<range[0]) range[0] = value; + if (value>range[1]) range[1] = value; + + unsigned char a[4] = { r, g, b, o }; + lut->setColor(value, a); + } + point = point.nextSiblingElement(); + } + + lut->SetTableRange(range[0], range[1]); + + delete file; + + return lut; + }; + + +}; + +#endif // XMLLUTREADER_H diff --git a/FileIO/XmlIO/XmlStnInterface.cpp b/FileIO/XmlIO/XmlStnInterface.cpp new file mode 100644 index 00000000000..a2e4f1f9f8f --- /dev/null +++ b/FileIO/XmlIO/XmlStnInterface.cpp @@ -0,0 +1,315 @@ +/** + * \file XmlStnInterface.cpp + * 2011/11/23 KR as derived class from XMLInterface + */ + +#include "XmlStnInterface.h" +#include "DateTools.h" +#include <limits> + +#include <QFile> +#include <QtXml/QDomDocument> + +namespace FileIO +{ + +XmlStnInterface::XmlStnInterface(ProjectData* project, const std::string &schemaFile) +: XMLInterface(project, schemaFile) +{ +} + +int XmlStnInterface::readFile(const QString &fileName) +{ + GeoLib::GEOObjects* geoObjects = _project->getGEOObjects(); + QFile* file = new QFile(fileName); + if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) + { + std::cout << "XmlStnInterface::readFile() - Can't open xml-file." << std::endl; + delete file; + return 0; + } + if (!checkHash(fileName)) + { + delete file; + return 0; + } + + QDomDocument doc("OGS-STN-DOM"); + doc.setContent(file); + QDomElement docElement = doc.documentElement(); //root element, used for identifying file-type + if (docElement.nodeName().compare("OpenGeoSysSTN")) + { + std::cout << "XmlStnInterface::readFile() - Unexpected XML root." << std::endl; + delete file; + return 0; + } + + QDomNodeList lists = docElement.childNodes(); + for (int i = 0; i < lists.count(); i++) + { + // read all the station lists + QDomNodeList stationList = lists.at(i).childNodes(); + std::vector<GeoLib::Point*>* stations = new std::vector<GeoLib::Point*>; + std::string stnName("[NN]"); + + for (int j = 0; j < stationList.count(); j++) + { + const QDomNode station_node(stationList.at(j)); + const QString station_type(station_node.nodeName()); + if (station_type.compare("name") == 0) + stnName = station_node.toElement().text().toStdString(); + else if (station_type.compare("stations") == 0) + readStations(station_node, stations); + else if (station_type.compare("boreholes") == 0) + readStations(station_node, stations); + } + + if (!stations->empty()) + geoObjects->addStationVec(stations, stnName); + else + delete stations; + } + + delete file; + + return 1; +} + +void XmlStnInterface::readStations( const QDomNode &stationsRoot, + std::vector<GeoLib::Point*>* stations ) +{ + QDomElement station = stationsRoot.firstChildElement(); + while (!station.isNull()) + { + if (station.hasAttribute("id") && station.hasAttribute("x") && + station.hasAttribute("y")) + { + std::string stationName("[NN]"); + std::string boreholeDate("0000-00-00"); + double boreholeDepth(0.0), stationValue(0.0); + + QDomNodeList stationFeatures = station.childNodes(); + for(int i = 0; i < stationFeatures.count(); i++) + { + const QDomNode feature_node (stationFeatures.at(i)); + const QString feature_name (feature_node.nodeName()); + const std::string element_text (feature_node.toElement().text().toStdString()); + if (feature_name.compare("name") == 0) + stationName = feature_node.toElement().text().toStdString(); + /* add other station features here */ + + else if (feature_name.compare("value") == 0) + stationValue = strtod(element_text.c_str(), 0); + else if (feature_name.compare("bdepth") == 0) + boreholeDepth = strtod(element_text.c_str(), 0); + else if (feature_name.compare("bdate") == 0) + boreholeDate = element_text; + /* add other borehole features here */ + } + + double zVal = (station.hasAttribute("z")) ? strtod((station.attribute( + "z")). + toStdString().c_str(), + 0) : 0.0; + + if (station.nodeName().compare("station") == 0) + { + GeoLib::Station* s = + new GeoLib::Station( + strtod((station.attribute("x")).toStdString().c_str(), 0), + strtod((station.attribute("y")).toStdString().c_str(), 0), + zVal, + stationName); + s->setStationValue(stationValue); + stations->push_back(s); + } + else if (station.nodeName().compare("borehole") == 0) + { + GeoLib::StationBorehole* s = GeoLib::StationBorehole::createStation( + stationName, + strtod((station.attribute("x")).toStdString().c_str(), 0), + strtod((station.attribute("y")).toStdString().c_str(), 0), + zVal, + boreholeDepth, + boreholeDate); + s->setStationValue(stationValue); + /* add stratigraphy to the borehole */ + for(int i = 0; i < stationFeatures.count(); i++) + if (stationFeatures.at(i).nodeName().compare("strat") == 0) + this->readStratigraphy(stationFeatures.at(i), s); + + stations->push_back(s); + } + } + else + std::cout << + "XmlStnInterface::readStations() - Attribute missing in <station> tag ..." << + std::endl; + station = station.nextSiblingElement(); + } +} + +void XmlStnInterface::readStratigraphy( const QDomNode &stratRoot, GeoLib::StationBorehole* borehole ) +{ + //borehole->addSoilLayer((*borehole)[0], (*borehole)[1], (*borehole)[2], ""); + double depth_check((*borehole)[2]); + QDomElement horizon = stratRoot.firstChildElement(); + while (!horizon.isNull()) + { + if (horizon.hasAttribute("id") && horizon.hasAttribute("x") && + horizon.hasAttribute("y") && horizon.hasAttribute("z")) + { + std::string horizonName("[NN]"); + + QDomNodeList horizonFeatures = horizon.childNodes(); + for(int i = 0; i < horizonFeatures.count(); i++) + if (horizonFeatures.at(i).nodeName().compare("name") == 0) + horizonName = horizonFeatures.at(i).toElement().text().toStdString(); + /* add other horizon features here */ + + double depth (strtod((horizon.attribute("z")).toStdString().c_str(), 0)); + if (fabs(depth - depth_check) < std::numeric_limits<double>::min()) // skip soil-layer if its thickness is zero + { + borehole->addSoilLayer(strtod((horizon.attribute("x")).toStdString().c_str(), 0), + strtod((horizon.attribute("y")).toStdString().c_str(), 0), + depth, + horizonName); + depth_check = depth; + } + else + std::cout << "Warning: Skipped layer \"" << horizonName << "\" in borehole \"" + << borehole->getName() << "\" because of thickness 0.0." << std::endl; + } + else + std::cout << + "XmlStnInterface::readStratigraphy() - Attribute missing in <horizon> tag ..." + << std::endl; + horizon = horizon.nextSiblingElement(); + } +} + +int XmlStnInterface::write(std::ostream& stream) +{ + if (this->_exportName.empty()) + { + std::cout << "Error in XmlStnInterface::write() - No station list specified..." << std::endl; + return 0; + } + + GeoLib::GEOObjects* geoObjects = _project->getGEOObjects(); + + stream << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"; // xml definition + stream << "<?xml-stylesheet type=\"text/xsl\" href=\"OpenGeoSysSTN.xsl\"?>\n\n"; // stylefile definition + + QDomDocument doc("OGS-STN-DOM"); + QDomElement root = doc.createElement("OpenGeoSysSTN"); + root.setAttribute( "xmlns:ogs", "http://www.opengeosys.net" ); + root.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" ); + root.setAttribute( "xsi:noNamespaceSchemaLocation", "http://141.65.34.25/OpenGeoSysSTN.xsd" ); + + const std::vector<GeoLib::Point*>* stations (geoObjects->getStationVec(_exportName)); + bool isBorehole = + (static_cast<GeoLib::Station*>((*stations)[0])->type() == + GeoLib::Station::BOREHOLE) ? true : false; + + doc.appendChild(root); + QDomElement stationListTag = doc.createElement("stationlist"); + root.appendChild(stationListTag); + + QDomElement listNameTag = doc.createElement("name"); + stationListTag.appendChild(listNameTag); + QDomText stationListNameText = doc.createTextNode(QString::fromStdString(_exportName)); + listNameTag.appendChild(stationListNameText); + QString listType = (isBorehole) ? "boreholes" : "stations"; + QDomElement stationsTag = doc.createElement(listType); + stationListTag.appendChild(stationsTag); + + bool useStationValue(false); + double sValue=static_cast<GeoLib::Station*>((*stations)[0])->getStationValue(); + size_t nStations(stations->size()); + for (size_t i = 1; i < nStations; i++) + if ((static_cast<GeoLib::Station*>((*stations)[i])->getStationValue() - sValue) < std::numeric_limits<double>::min()) + { + useStationValue = true; + break; + } + + for (size_t i = 0; i < nStations; i++) + { + QString stationType = (isBorehole) ? "borehole" : "station"; + QDomElement stationTag = doc.createElement(stationType); + stationTag.setAttribute( "id", QString::number(i) ); + stationTag.setAttribute( "x", QString::number((*(*stations)[i])[0], 'f') ); + stationTag.setAttribute( "y", QString::number((*(*stations)[i])[1], 'f') ); + stationTag.setAttribute( "z", QString::number((*(*stations)[i])[2], 'f') ); + stationsTag.appendChild(stationTag); + + QDomElement stationNameTag = doc.createElement("name"); + stationTag.appendChild(stationNameTag); + QDomText stationNameText = + doc.createTextNode(QString::fromStdString(static_cast<GeoLib::Station*>((*stations)[i])->getName())); + stationNameTag.appendChild(stationNameText); + + if (useStationValue) + { + QDomElement stationValueTag = doc.createElement("value"); + stationTag.appendChild(stationValueTag); + QDomText stationValueText = + doc.createTextNode(QString::number(static_cast<GeoLib::Station*>((*stations)[i])->getStationValue())); + stationValueTag.appendChild(stationValueText); + } + + if (isBorehole) + writeBoreholeData(doc, stationTag, + static_cast<GeoLib::StationBorehole*>((*stations)[i])); + } + + std::string xml = doc.toString().toStdString(); + stream << xml; + return 1; +} + +void XmlStnInterface::writeBoreholeData(QDomDocument &doc, + QDomElement &boreholeTag, + GeoLib::StationBorehole* borehole) const +{ + QDomElement stationDepthTag = doc.createElement("bdepth"); + boreholeTag.appendChild(stationDepthTag); + QDomText stationDepthText = doc.createTextNode(QString::number(borehole->getDepth(), 'f')); + stationDepthTag.appendChild(stationDepthText); + if (fabs(borehole->getDate()) > 0) + { + QDomElement stationDateTag = doc.createElement("bdate"); + boreholeTag.appendChild(stationDateTag); + QDomText stationDateText = + doc.createTextNode(QString::fromStdString(BaseLib::date2string(borehole->getDate()))); + stationDateTag.appendChild(stationDateText); + } + + std::vector<GeoLib::Point*> profile = borehole->getProfile(); + std::vector<std::string> soilNames = borehole->getSoilNames(); + size_t nHorizons(profile.size()); + + if (nHorizons > 1) + { + QDomElement stratTag = doc.createElement("strat"); + boreholeTag.appendChild(stratTag); + + for (size_t j = 1; j < nHorizons; j++) /// the first entry in the profile vector is just the position of the borehole + { + QDomElement horizonTag = doc.createElement("horizon"); + horizonTag.setAttribute( "id", QString::number(j) ); + horizonTag.setAttribute( "x", QString::number((*profile[j])[0], 'f') ); + horizonTag.setAttribute( "y", QString::number((*profile[j])[1], 'f') ); + horizonTag.setAttribute( "z", QString::number((*profile[j])[2], 'f') ); + stratTag.appendChild(horizonTag); + QDomElement horizonNameTag = doc.createElement("name"); + horizonTag.appendChild(horizonNameTag); + QDomText horizonNameText = + doc.createTextNode(QString::fromStdString(soilNames[j])); + horizonNameTag.appendChild(horizonNameText); + } + } +} + +} diff --git a/FileIO/XmlIO/XmlStnInterface.h b/FileIO/XmlIO/XmlStnInterface.h new file mode 100644 index 00000000000..91267099823 --- /dev/null +++ b/FileIO/XmlIO/XmlStnInterface.h @@ -0,0 +1,48 @@ +/** + * \file XmlStnInterface.h + * 2011/11/23 KR as derived class from XMLInterface + */ + +#ifndef XMLSTNINTERFACE_H +#define XMLSTNINTERFACE_H + +#include "XMLInterface.h" + +namespace FileIO +{ + +/** + * \brief Reads and writes Observation Sites to and from XML files. + */ +class XmlStnInterface : public XMLInterface +{ +public: + /** + * Constructor + * \param project Project data. + * \param schemaFile An XML schema file (*.xsd) that defines the structure of a valid data file. + */ + XmlStnInterface(ProjectData* project, const std::string &schemaFile); + + /// Reads an xml-file containing station object definitions into the GEOObjects used in the contructor + int readFile(const QString &fileName); + +protected: + int write(std::ostream& stream); + +private: + /// Reads GeoLib::Station- or StationBorehole-objects from an xml-file + void readStations ( const QDomNode &stationsRoot, std::vector<GeoLib::Point*>* stations ); + + /// Writes borehole-specific data to a station-xml-file. + void writeBoreholeData(QDomDocument &doc, + QDomElement &boreholeTag, + GeoLib::StationBorehole* borehole) const; + + /// Reads the stratigraphy of a borehole from an xml-file + void readStratigraphy( const QDomNode &stratRoot, GeoLib::StationBorehole* borehole ); +}; + +} + +#endif // XMLSTNINTERFACE_H diff --git a/GeoLib/GEOObjects.cpp b/GeoLib/GEOObjects.cpp index 7fd5776431e..866172c27aa 100644 --- a/GeoLib/GEOObjects.cpp +++ b/GeoLib/GEOObjects.cpp @@ -10,8 +10,8 @@ #include <fstream> -namespace GeoLib { - +namespace GeoLib +{ GEOObjects::GEOObjects() { } @@ -19,146 +19,165 @@ GEOObjects::GEOObjects() GEOObjects::~GEOObjects() { // delete surfaces - for (size_t k(0); k < _sfc_vecs.size(); k++) { + for (size_t k(0); k < _sfc_vecs.size(); k++) delete _sfc_vecs[k]; - } // delete polylines - for (size_t k(0); k < _ply_vecs.size(); k++) { + for (size_t k(0); k < _ply_vecs.size(); k++) delete _ply_vecs[k]; - } // delete points - for (size_t k(0); k < _pnt_vecs.size(); k++) { + for (size_t k(0); k < _pnt_vecs.size(); k++) delete _pnt_vecs[k]; - } } -void GEOObjects::addPointVec(std::vector<Point*> *points, std::string &name, std::map<std::string, size_t>* pnt_id_name_map) +void GEOObjects::addPointVec(std::vector<Point*>* points, + std::string &name, + std::map<std::string, size_t>* pnt_id_name_map, + double eps) { isUniquePointVecName(name); - _pnt_vecs.push_back(new PointVec(name, points, pnt_id_name_map)); -// std::cout << "minimal dist between points: " << (_pnt_vecs[_pnt_vecs.size()-1])->getShortestPointDistance () << std::endl; + _pnt_vecs.push_back(new PointVec(name, points, pnt_id_name_map, PointVec::POINT, eps)); } bool GEOObjects::appendPointVec(std::vector<Point*> const& new_points, - std::string const &name, std::vector<size_t>* ids) + std::string const &name, std::vector<size_t>* ids) { // search vector - size_t idx (0); - bool nfound (true); - for (idx=0; idx<_pnt_vecs.size() && nfound; idx++) { - if ( (_pnt_vecs[idx]->getName()).compare (name) == 0 ) - nfound = false; - } + int idx = this->exists(name); - if (! nfound) { - idx--; + if (idx>=0) { size_t n_new_pnts (new_points.size()); // append points - if (ids) { - for (size_t k(0); k<n_new_pnts; k++) { + if (ids) + for (size_t k(0); k < n_new_pnts; k++) ids->push_back (_pnt_vecs[idx]->push_back (new_points[k])); - } - } else { - for (size_t k(0); k<n_new_pnts; k++) { + else + for (size_t k(0); k < n_new_pnts; k++) _pnt_vecs[idx]->push_back (new_points[k]); - } - } + return true; - } else return false; + } else + return false; +} + +bool GEOObjects::appendPoint(Point* point, std::string const &name, size_t& id) +{ + // search vector + int idx = this->exists(name); + + if (idx>=0) { + const size_t size_previous (_pnt_vecs[idx]->size()); + id = _pnt_vecs[idx]->push_back (point); + if (size_previous < _pnt_vecs[idx]->size()) { + return true; + } else { + return false; + } + } else { + return false; + } } const std::vector<Point*>* GEOObjects::getPointVec(const std::string &name) const { + int idx = this->exists(name); + if (idx>=0) return _pnt_vecs[idx]->getVector(); +/* size_t size (_pnt_vecs.size()); - for (size_t i=0; i<size; i++) - { - if (_pnt_vecs[i]->getName().compare(name)==0) + for (size_t i = 0; i < size; i++) + if (_pnt_vecs[i]->getName().compare(name) == 0) return _pnt_vecs[i]->getVector(); - } +*/ std::cout << "GEOObjects::getPointVec() - No entry found with name \"" << name << "\"." << std::endl; return NULL; } const PointVec* GEOObjects::getPointVecObj(const std::string &name) const { + int idx = this->exists(name); + if (idx>=0) return _pnt_vecs[idx]; +/* size_t size (_pnt_vecs.size()); - for (size_t i=0; i<size; i++) { - if (_pnt_vecs[i]->getName().compare(name)==0) + for (size_t i = 0; i < size; i++) + if (_pnt_vecs[i]->getName().compare(name) == 0) return _pnt_vecs[i]; - } - std::cout << "GEOObjects::getPointVec() - No entry found with name \"" << name << "\"." << std::endl; +*/ + std::cout << "GEOObjects::getPointVecObj() - No entry found with name \"" << name << "\"." << std::endl; return NULL; } bool GEOObjects::removePointVec(const std::string &name) { - if (isPntVecUsed (name)) { - std::cout << "GEOObjects::removePointVec() - There are still Polylines or Surfaces depending on these points." << std::endl; + if (isPntVecUsed (name)) + { + std::cout << + "GEOObjects::removePointVec() - There are still Polylines or Surfaces depending on these points." + << std::endl; return false; } for (std::vector<PointVec*>::iterator it(_pnt_vecs.begin()); - it != _pnt_vecs.end(); it++) { - if ((*it)->getName().compare(name)==0) { + it != _pnt_vecs.end(); it++) + if ((*it)->getName().compare(name) == 0) + { delete *it; _pnt_vecs.erase(it); return true; } - } - std::cout << "GEOObjects::removePointVec() - No entry found with name \"" << name << "." << std::endl; + std::cout << "GEOObjects::removePointVec() - No entry found with name \"" << name << "." << + std::endl; return false; } - -void GEOObjects::addStationVec(std::vector<Point*> *stations, std::string &name, const Color* const color) +void GEOObjects::addStationVec(std::vector<Point*>* stations, std::string &name) { - size_t size = stations->size(); - for (size_t i=0; i<size; i++) static_cast<Station*>((*stations)[i])->setColor(color); isUniquePointVecName(name); _pnt_vecs.push_back(new PointVec(name, stations, NULL, PointVec::STATION)); } - -std::vector<Point*> *GEOObjects::filterStationVec(const std::string &name, - const std::vector<PropertyBounds> &bounds) +std::vector<Point*>* GEOObjects::filterStationVec(const std::string &name, + const std::vector<PropertyBounds> &bounds) { for (std::vector<PointVec*>::iterator it(_pnt_vecs.begin()); - it != _pnt_vecs.end(); it++) { + it != _pnt_vecs.end(); it++) if ((*it)->getName().compare(name) == 0 && (*it)->getType() - == PointVec::STATION) { + == PointVec::STATION) return (*it)->filterStations(bounds); - } - } + std::cout << "GEOObjects:: filterStations() - No entry found with name \"" - << name << "." << std::endl; + << name << "." << std::endl; return NULL; } -const std::vector<Point*> *GEOObjects::getStationVec(const std::string &name) const +const std::vector<Point*>* GEOObjects::getStationVec(const std::string &name) const { for (std::vector<PointVec*>::const_iterator it(_pnt_vecs.begin()); - it != _pnt_vecs.end(); it++) { - if ((*it)->getName().compare(name) == 0 && (*it)->getType() - == PointVec::STATION) + it != _pnt_vecs.end(); it++) { + if ((*it)->getName().compare(name) == 0 && (*it)->getType() == PointVec::STATION) { return (*it)->getVector(); + } } std::cout << "GEOObjects::getStationVec() - No entry found with name \"" - << name << "." << std::endl; + << name << "." << std::endl; return NULL; } -void GEOObjects::addPolylineVec(std::vector<Polyline*> *lines, - const std::string &name, std::map<std::string, size_t>* ply_names) +void GEOObjects::addPolylineVec(std::vector<Polyline*>* lines, + const std::string &name, std::map<std::string, size_t>* ply_names) { for (std::vector<Polyline*>::iterator it (lines->begin()); - it != lines->end(); ) { - if ((*it)->getNumberOfPoints() < 2) { + it != lines->end(); ) + { + if ((*it)->getNumberOfPoints() < 2) + { std::vector<Polyline*>::iterator it_erase (it); it = lines->erase (it_erase); - } else it++; + } + else + it++; } - if (lines->empty()) return; + if (lines->empty()) + return; _ply_vecs.push_back(new PolylineVec(name, lines, ply_names)); } @@ -168,30 +187,33 @@ bool GEOObjects::appendPolylineVec(const std::vector<Polyline*> &polylines, cons // search vector size_t idx (0); bool nfound (true); - for (idx=0; idx<_ply_vecs.size() && nfound; idx++) { - if ( (_ply_vecs[idx]->getName()).compare (name) == 0 ) nfound = false; - } + for (idx = 0; idx < _ply_vecs.size() && nfound; idx++) + if ( (_ply_vecs[idx]->getName()).compare (name) == 0 ) + nfound = false; - if (! nfound) { + if (!nfound) + { idx--; size_t n_plys (polylines.size()); // append lines - for (size_t k(0); k<n_plys; k++) + for (size_t k(0); k < n_plys; k++) _ply_vecs[idx]->push_back (polylines[k]); return true; - } else return false; + } + else + return false; } -const std::vector<Polyline*> *GEOObjects::getPolylineVec(const std::string &name) const +const std::vector<Polyline*>* GEOObjects::getPolylineVec(const std::string &name) const { size_t size (_ply_vecs.size()); - for (size_t i=0; i<size; i++) - { - if (_ply_vecs[i]->getName().compare(name)==0) + for (size_t i = 0; i < size; i++) + if (_ply_vecs[i]->getName().compare(name) == 0) return _ply_vecs[i]->getVector(); - } + #ifndef NDEBUG - std::cout << "DEB: GEOObjects::getPolylineVec() - No entry found with name \"" << name << "." << std::endl; + std::cout << "DEB: GEOObjects::getPolylineVec() - No entry found with name \"" << name << + "." << std::endl; #endif return NULL; } @@ -199,12 +221,13 @@ const std::vector<Polyline*> *GEOObjects::getPolylineVec(const std::string &name const PolylineVec* GEOObjects::getPolylineVecObj(const std::string &name) const { size_t size (_ply_vecs.size()); - for (size_t i=0; i<size; i++) { - if (_ply_vecs[i]->getName().compare(name)==0) + for (size_t i = 0; i < size; i++) + if (_ply_vecs[i]->getName().compare(name) == 0) return _ply_vecs[i]; - } + #ifndef NDEBUG - std::cout << "DEB: GEOObjects::getPolylineVec() - No entry found with name \"" << name << "\"." << std::endl; + std::cout << "DEB: GEOObjects::getPolylineVecObj() - No entry found with name \"" << name << + "\"." << std::endl; #endif return NULL; } @@ -212,23 +235,23 @@ const PolylineVec* GEOObjects::getPolylineVecObj(const std::string &name) const bool GEOObjects::removePolylineVec(const std::string &name) { for (std::vector<PolylineVec*>::iterator it = _ply_vecs.begin(); - it != _ply_vecs.end(); ++it) - { - if ((*it)->getName().compare(name) == 0) { + it != _ply_vecs.end(); ++it) + if ((*it)->getName().compare(name) == 0) + { delete *it; _ply_vecs.erase(it); return true; } - } + #ifndef NDEBUG std::cout << "GEOObjects::removePolylineVec() - No entry found with name \"" - << name << "\"." << std::endl; + << name << "\"." << std::endl; #endif return false; } -void GEOObjects::addSurfaceVec(std::vector<Surface*> *sfc, const std::string &name, - std::map<std::string, size_t>* sfc_names) +void GEOObjects::addSurfaceVec(std::vector<Surface*>* sfc, const std::string &name, + std::map<std::string, size_t>* sfc_names) { _sfc_vecs.push_back(new SurfaceVec(name, sfc, sfc_names)); } @@ -238,45 +261,48 @@ bool GEOObjects::appendSurfaceVec(const std::vector<Surface*> &surfaces, const s // search vector size_t idx (0); bool nfound (true); - for (idx=0; idx<_sfc_vecs.size() && nfound; idx++) { - if ( (_sfc_vecs[idx]->getName()).compare (name) == 0 ) nfound = false; - } + for (idx = 0; idx < _sfc_vecs.size() && nfound; idx++) + if ( (_sfc_vecs[idx]->getName()).compare (name) == 0 ) + nfound = false; - if (! nfound) { + if (!nfound) + { idx--; size_t n_sfcs (surfaces.size()); // append surfaces - for (size_t k(0); k<n_sfcs; k++) + for (size_t k(0); k < n_sfcs; k++) _sfc_vecs[idx]->push_back (surfaces[k]); return true; - } else return false; + } + else + return false; } const std::vector<Surface*>* GEOObjects::getSurfaceVec(const std::string &name) const { size_t size (_sfc_vecs.size()); - for (size_t i=0; i<size; i++) - { - if (_sfc_vecs[i]->getName().compare(name)==0) + for (size_t i = 0; i < size; i++) + if (_sfc_vecs[i]->getName().compare(name) == 0) return _sfc_vecs[i]->getVector(); - } - std::cout << "GEOObjects::getSurfaceVec() - No entry found with name \"" << name << "." << std::endl; + std::cout << "GEOObjects::getSurfaceVec() - No entry found with name \"" << name << "." << + std::endl; return NULL; } bool GEOObjects::removeSurfaceVec(const std::string &name) { for (std::vector<SurfaceVec*>::iterator it (_sfc_vecs.begin()); - it != _sfc_vecs.end(); it++) { - if ((*it)->getName().compare (name) == 0) { + it != _sfc_vecs.end(); it++) + if ((*it)->getName().compare (name) == 0) + { delete *it; _sfc_vecs.erase (it); return true; } - } + #ifndef NDEBUG std::cout << "GEOObjects::removeSurfaceVec() - No entry found with name \"" - << name << "\"." << std::endl; + << name << "\"." << std::endl; #endif return false; } @@ -284,17 +310,17 @@ bool GEOObjects::removeSurfaceVec(const std::string &name) const SurfaceVec* GEOObjects::getSurfaceVecObj(const std::string &name) const { size_t size (_sfc_vecs.size()); - for (size_t i=0; i<size; i++) { - if (_sfc_vecs[i]->getName().compare(name)==0) + for (size_t i = 0; i < size; i++) + if (_sfc_vecs[i]->getName().compare(name) == 0) return _sfc_vecs[i]; - } - std::cout << "GEOObjects::getSurfaceVec() - No entry found with name \"" << name << "\"." << std::endl; + std::cout << "GEOObjects::getSurfaceVecObj() - No entry found with name \"" << name << + "\"." << std::endl; return NULL; } bool GEOObjects::isUniquePointVecName(std::string &name) { - int count=0; + int count = 0; bool isUnique = false; std::string cpName; @@ -306,18 +332,18 @@ bool GEOObjects::isUniquePointVecName(std::string &name) count++; // If the original name already exists we start to add numbers to name for // as long as it takes to make the name unique. - if (count>1) cpName = cpName + "-" + number2str(count); + if (count > 1) + cpName = cpName + "-" + number2str(count); - for (size_t i=0; i<_pnt_vecs.size(); i++) - { - if ( cpName.compare(_pnt_vecs[i]->getName()) == 0 ) isUnique = false; - } + for (size_t i = 0; i < _pnt_vecs.size(); i++) + if ( cpName.compare(_pnt_vecs[i]->getName()) == 0 ) + isUnique = false; } // At this point cpName is a unique name and isUnique is true. // If cpName is not the original name, "name" is changed and isUnique is set to false, // indicating that a vector with the original name already exists. - if (count>1) + if (count > 1) { isUnique = false; name = cpName; @@ -328,13 +354,15 @@ bool GEOObjects::isUniquePointVecName(std::string &name) bool GEOObjects::isPntVecUsed (const std::string &name) const { // search dependent data structures (Polyline) - for (std::vector<PolylineVec*>::const_iterator it ( _ply_vecs.begin()); it != _ply_vecs.end(); it++) + for (std::vector<PolylineVec*>::const_iterator it ( _ply_vecs.begin()); it != _ply_vecs.end(); + it++) { std::string a = (*it)->getName(); if (((*it)->getName()).compare(name) == 0) return true; } - for (std::vector<SurfaceVec*>::const_iterator it ( _sfc_vecs.begin()); it != _sfc_vecs.end(); it++) + for (std::vector<SurfaceVec*>::const_iterator it ( _sfc_vecs.begin()); it != _sfc_vecs.end(); + it++) { std::string a = (*it)->getName(); if (((*it)->getName()).compare(name) == 0) @@ -342,63 +370,84 @@ bool GEOObjects::isPntVecUsed (const std::string &name) const } return false; - } -void GEOObjects::getStationNames(std::vector<std::string>& names) const +void GEOObjects::getStationVectorNames(std::vector<std::string>& names) const { - for (std::vector<PointVec*>::const_iterator it(_pnt_vecs.begin()); it != _pnt_vecs.end(); it++) { + for (std::vector<PointVec*>::const_iterator it(_pnt_vecs.begin()); it != _pnt_vecs.end(); + it++) if ((*it)->getType() == PointVec::STATION) names.push_back((*it)->getName()); - } } void GEOObjects::getGeometryNames (std::vector<std::string>& names) const { names.clear (); - for (std::vector<PointVec*>::const_iterator it(_pnt_vecs.begin()); it != _pnt_vecs.end(); it++) { + for (std::vector<PointVec*>::const_iterator it(_pnt_vecs.begin()); it != _pnt_vecs.end(); + it++) if ((*it)->getType() == PointVec::POINT) names.push_back((*it)->getName()); +} + +const std::string GEOObjects::getElementNameByID(const std::string &geometry_name, GeoLib::GEOTYPE type, size_t id) const +{ + std::string name(""); + switch (type) + { + case GeoLib::POINT: + this->getPointVecObj(geometry_name)->getNameOfElementByID(id, name); + break; + case GeoLib::POLYLINE: + this->getPolylineVecObj(geometry_name)->getNameOfElementByID(id, name); + break; + case GeoLib::SURFACE: + this->getSurfaceVecObj(geometry_name)->getNameOfElementByID(id, name); + break; + default: + std::cout << "No valid GEOTYPE given." << std::endl; } + return name; } -void GEOObjects::mergeGeometries (std::vector<std::string> const & geo_names, std::string &merged_geo_name) +void GEOObjects::mergeGeometries (std::vector<std::string> const & geo_names, + std::string &merged_geo_name) { - std::vector<size_t> pnt_offsets(geo_names.size(), 0); + const size_t n_geo_names(geo_names.size()); + std::vector<size_t> pnt_offsets(n_geo_names, 0); // *** merge points std::vector<GeoLib::Point*>* merged_points (new std::vector<GeoLib::Point*>); - for (size_t j(0); j<geo_names.size(); j++) { + for (size_t j(0); j < n_geo_names; j++) { const std::vector<GeoLib::Point*>* pnts (this->getPointVec(geo_names[j])); if (pnts) { - size_t nPoints(0); + size_t n_pnts(0); // do not consider stations if (dynamic_cast<GeoLib::Station*>((*pnts)[0]) == NULL) { - nPoints = pnts->size(); - for (size_t k(0); k<nPoints; k++) { + n_pnts = pnts->size(); + for (size_t k(0); k < n_pnts; k++) merged_points->push_back (new GeoLib::Point (((*pnts)[k])->getCoords())); - } } - if (geo_names.size()-1 > j) - pnt_offsets[j+1] = nPoints + pnt_offsets[j]; + if (n_geo_names - 1 > j) { + pnt_offsets[j + 1] = n_pnts + pnt_offsets[j]; + } } } - - this->addPointVec (merged_points, merged_geo_name); + addPointVec (merged_points, merged_geo_name, NULL, 1e-6); std::vector<size_t> const& id_map (this->getPointVecObj(merged_geo_name)->getIDMap ()); // *** merge polylines - std::vector<GeoLib::Polyline*> *merged_polylines (new std::vector<GeoLib::Polyline*>); - for (size_t j(0); j<geo_names.size(); j++) { + std::vector<GeoLib::Polyline*>* merged_polylines (new std::vector<GeoLib::Polyline*>); + for (size_t j(0); j < n_geo_names; j++) { const std::vector<GeoLib::Polyline*>* plys (this->getPolylineVec(geo_names[j])); if (plys) { - for (size_t k(0); k<plys->size(); k++) { + for (size_t k(0); k < plys->size(); k++) { GeoLib::Polyline* kth_ply_new(new GeoLib::Polyline (*merged_points)); - GeoLib::Polyline const*const kth_ply_old ((*plys)[k]); + GeoLib::Polyline const* const kth_ply_old ((*plys)[k]); const size_t size_of_kth_ply (kth_ply_old->getNumberOfPoints()); // copy point ids from old ply to new ply (considering the offset) - for (size_t i(0); i<size_of_kth_ply; i++) { - kth_ply_new->addPoint (id_map[pnt_offsets[j]+kth_ply_old->getPointID(i)]); + for (size_t i(0); i < size_of_kth_ply; i++) { + kth_ply_new->addPoint (id_map[pnt_offsets[j] + + kth_ply_old->getPointID(i)]); } merged_polylines->push_back (kth_ply_new); } @@ -406,22 +455,21 @@ void GEOObjects::mergeGeometries (std::vector<std::string> const & geo_names, st } this->addPolylineVec (merged_polylines, merged_geo_name); - // *** merge surfaces - std::vector<GeoLib::Surface*> *merged_sfcs (new std::vector<GeoLib::Surface*>); - for (size_t j(0); j<geo_names.size(); j++) { + std::vector<GeoLib::Surface*>* merged_sfcs (new std::vector<GeoLib::Surface*>); + for (size_t j(0); j < n_geo_names; j++) { const std::vector<GeoLib::Surface*>* sfcs (this->getSurfaceVec(geo_names[j])); if (sfcs) { - for (size_t k(0); k<sfcs->size(); k++) { + for (size_t k(0); k < sfcs->size(); k++) { GeoLib::Surface* kth_sfc_new(new GeoLib::Surface (*merged_points)); - GeoLib::Surface const*const kth_sfc_old ((*sfcs)[k]); + GeoLib::Surface const* const kth_sfc_old ((*sfcs)[k]); const size_t size_of_kth_sfc (kth_sfc_old->getNTriangles()); // copy point ids from old ply to new ply (considering the offset) - for (size_t i(0); i<size_of_kth_sfc; i++) { + for (size_t i(0); i < size_of_kth_sfc; i++) { const GeoLib::Triangle* tri ((*kth_sfc_old)[i]); - const size_t id0 (id_map[pnt_offsets[j]+(*tri)[0]]); - const size_t id1 (id_map[pnt_offsets[j]+(*tri)[1]]); - const size_t id2 (id_map[pnt_offsets[j]+(*tri)[2]]); + const size_t id0 (id_map[pnt_offsets[j] + (*tri)[0]]); + const size_t id1 (id_map[pnt_offsets[j] + (*tri)[1]]); + const size_t id2 (id_map[pnt_offsets[j] + (*tri)[2]]); kth_sfc_new->addTriangle (id0, id1, id2); } merged_sfcs->push_back (kth_sfc_new); @@ -431,5 +479,32 @@ void GEOObjects::mergeGeometries (std::vector<std::string> const & geo_names, st this->addSurfaceVec (merged_sfcs, merged_geo_name); } +const GeoLib::GeoObject* GEOObjects::getGEOObject(const std::string &geo_name, + GeoLib::GEOTYPE type, + const std::string &obj_name) const +{ + if (type == GeoLib::POINT) + return this->getPointVecObj(geo_name)->getElementByName(obj_name); + else if (type == GeoLib::POLYLINE) + return this->getPolylineVecObj(geo_name)->getElementByName(obj_name); + else if (type == GeoLib::SURFACE) + return this->getSurfaceVecObj(geo_name)->getElementByName(obj_name); + return NULL; +} + +int GEOObjects::exists(const std::string &geometry_name) const +{ + size_t size (_pnt_vecs.size()); + for (size_t i = 0; i < size; i++) + if (_pnt_vecs[i]->getName().compare(geometry_name) == 0) + return i; + + // HACK for enabling conversion of files without loading the associated geometry + if (size>0 && _pnt_vecs[0]->getName().compare("conversionTestRun#1")==0) + return 1; + + return -1; +} + } // namespace diff --git a/GeoLib/GEOObjects.h b/GeoLib/GEOObjects.h index bf0d8f1305b..5525432c250 100644 --- a/GeoLib/GEOObjects.h +++ b/GeoLib/GEOObjects.h @@ -8,22 +8,24 @@ #ifndef GEOOBJECTS_H_ #define GEOOBJECTS_H_ -#include <vector> -#include <string> #include <map> +#include <string> +#include <vector> -#include "PointVec.h" #include "Point.h" -#include "PolylineVec.h" +#include "PointVec.h" #include "Polyline.h" -#include "SurfaceVec.h" +#include "PolylineVec.h" #include "Surface.h" +#include "SurfaceVec.h" #include "Color.h" #include "Station.h" -namespace GeoLib { +#include "GeoType.h" +namespace GeoLib +{ /// /** * \defgroup GeoLib This module consists of classes governing geometric objects @@ -52,19 +54,24 @@ namespace GeoLib { * "removePointVec(name)". For some objects, additional methods might exist if * necessary. */ -class GEOObjects { +class GEOObjects +{ public: /** * Adds a vector of points with the given name to GEOObjects. * @param points vector of pointers to points * @param name the project name * @param pnt_names vector of the names corresponding to the points + * @param eps relative tolerance value for testing of point uniqueness */ - virtual void addPointVec(std::vector<Point*> *points, std::string &name, std::map<std::string, size_t>* pnt_names = NULL); - - /** copies the pointers to the points in the vector to the PointVec with provided name. - * the pointers are managed by the GEOObjects, i.e. GEOObjects will delete the Points at the - * end of its scope + virtual void addPointVec(std::vector<Point*>* points, + std::string &name, + std::map<std::string, size_t>* pnt_names = NULL, + double eps = sqrt(std::numeric_limits<double>::min())); + + /** copies the pointers to the points in the given vector to the PointVec of the provided name. + * The pointers are managed by the GEOObjects, i.e. GEOObjects will delete the Points at the + * end of its scope. * \param points the vector with points * \param name the name of the internal PointVec * \param ids On return the vector holds the ids of the inserted points within the internal vector. @@ -73,12 +80,24 @@ public: * corresponding name does not exist * */ virtual bool appendPointVec(const std::vector<Point*> &points, - std::string const &name, std::vector<size_t>* ids = NULL); + std::string const &name, std::vector<size_t>* ids = NULL); + + /** + * Method appends the point the the PointVec object with the name name. The PointVec + * object takes care about deleting the point. If the point already exists within the + * PointVec object this method will delete it. + * @param point (input) the point (exact the pointer to the point) that should be added + * @param name (input) the name of the geometry the point should be added + * @param id (output) the id of the point within the PointVec object will be set + * @return true, if the point could be inserted (i.e. was not already contained in the vector) + * else false (the user have to delete the point itself) + */ + bool appendPoint(Point* point, std::string const &name, size_t& id); /** * Returns the point vector with the given name. */ - const std::vector<Point*> *getPointVec(const std::string &name) const; + const std::vector<Point*>* getPointVec(const std::string &name) const; /** * search and returns the PointVec object with the given name. @@ -87,6 +106,13 @@ public: */ const PointVec* getPointVecObj(const std::string &name) const; + /// Returns a pointer to a PointVec object for the given name. + PointVec* getPointVecObj(const std::string &name) + { + return const_cast<PointVec*>(static_cast<const GEOObjects&>(*this). + getPointVecObj(name)); + } + /** If there exists no dependencies the point vector with the given * name from GEOObjects will be removed and the method returns true, * else the return value is false. @@ -94,29 +120,30 @@ public: virtual bool removePointVec(const std::string &name); /// Adds a vector of stations with the given name and colour to GEOObjects. - virtual void addStationVec(std::vector<Point*> *stations, std::string &name, - const Color* const color); + virtual void addStationVec(std::vector<Point*>* stations, std::string &name); + /// Filters a list of stations with the given name based on the criteria in PropertyBounds. /// (See property system in Station class for more information.) - std::vector<Point*> *filterStationVec(const std::string &name, - const std::vector<PropertyBounds> &bounds); + std::vector<Point*>* filterStationVec(const std::string &name, + const std::vector<PropertyBounds> &bounds); /// Returns the station vector with the given name. - const std::vector<Point*> *getStationVec(const std::string &name) const; + const std::vector<Point*>* getStationVec(const std::string &name) const; /// Removes the station vector with the given name from GEOObjects - virtual bool removeStationVec(const std::string &name) { + virtual bool removeStationVec(const std::string &name) + { return removePointVec(name); } - /** * Adds a vector of polylines with the given name to GEOObjects. * @param lines The lines vector. * @param name The given name. * @param ply_names vector of the names corresponding to the polylines - */ - virtual void addPolylineVec(std::vector<Polyline*> *lines, - const std::string &name, std::map<std::string,size_t>* ply_names = NULL); + */ + virtual void addPolylineVec(std::vector<Polyline*>* lines, + const std::string &name, + std::map<std::string,size_t>* ply_names = NULL); /** copies the pointers to the polylines in the vector to the PolylineVec with provided name. * the pointers are managed by the GEOObjects, i.e. GEOObjects will delete the Polylines at the @@ -127,12 +154,12 @@ public: * corresponding name does not exist * */ virtual bool appendPolylineVec(const std::vector<Polyline*> &polylines, - const std::string &name); + const std::string &name); /** * Returns the polyline vector with the given name. * */ - const std::vector<Polyline*> *getPolylineVec(const std::string &name) const; + const std::vector<Polyline*>* getPolylineVec(const std::string &name) const; /** * Returns a pointer to a PolylineVec object for the given name as a const. @@ -142,9 +169,11 @@ public: const PolylineVec* getPolylineVecObj(const std::string &name) const; /// Returns a pointer to a PolylineVec object for the given name. - PolylineVec* getPolylineVecObj(const std::string &name) { - return const_cast<PolylineVec*>(static_cast<const GEOObjects&>(*this).getPolylineVecObj(name)); - }; + PolylineVec* getPolylineVecObj(const std::string &name) + { + return const_cast<PolylineVec*>(static_cast<const GEOObjects&>(*this). + getPolylineVecObj(name)); + } /** * If no Surfaces depends on the vector of Polylines with the given @@ -154,8 +183,9 @@ public: virtual bool removePolylineVec(const std::string &name); /** Adds a vector of surfaces with the given name to GEOObjects. */ - virtual void addSurfaceVec(std::vector<Surface*> *surfaces, - const std::string &name, std::map<std::string, size_t>* sfc_names = NULL); + virtual void addSurfaceVec(std::vector<Surface*>* surfaces, + const std::string &name, + std::map<std::string, size_t>* sfc_names = NULL); /** * Copies the surfaces in the vector to the SurfaceVec with the given name. @@ -165,15 +195,17 @@ public: * corresponding name does not exist * */ virtual bool appendSurfaceVec(const std::vector<Surface*> &surfaces, - const std::string &name); + const std::string &name); /// Returns the surface vector with the given name as a const. - const std::vector<Surface*> *getSurfaceVec(const std::string &name) const; + const std::vector<Surface*>* getSurfaceVec(const std::string &name) const; /// Returns the surface vector with the given name. - SurfaceVec* getSurfaceVecObj(const std::string &name) { - return const_cast<SurfaceVec*>(static_cast<const GEOObjects&>(*this).getSurfaceVecObj(name)); - }; + SurfaceVec* getSurfaceVecObj(const std::string &name) + { + return const_cast<SurfaceVec*>(static_cast<const GEOObjects&>(*this). + getSurfaceVecObj(name)); + } /** removes the vector of Surfaces with the given name */ virtual bool removeSurfaceVec(const std::string &name); @@ -185,18 +217,29 @@ public: */ const SurfaceVec* getSurfaceVecObj(const std::string &name) const; + /// Returns -1 if no geometry of the given name exists or die index of the geometry in _pnt_vecs otherwise + int exists(const std::string &geometry_name) const; + /// Returns the names of all geometry vectors. void getGeometryNames (std::vector<std::string>& names) const; + const std::string getElementNameByID(const std::string &geometry_name, GeoLib::GEOTYPE type, size_t id) const; + /// Returns the names of all station vectors. - void getStationNames(std::vector<std::string>& names) const; + void getStationVectorNames(std::vector<std::string>& names) const; /** - * merge geometries + * Method mergeGeometries merges the geometries that are given by the names in the vector. + * Stations points are not included in the resulting merged geometry. * @param names the names of the geometries that are to be merged * @param merged_geo_name the name of the resulting geometry */ - void mergeGeometries (std::vector<std::string> const & names, std::string &merged_geo_name); + void mergeGeometries(std::vector<std::string> const & names, std::string &merged_geo_name); + + /// Returns the geo object for a geometric item of the given name and type for the associated geometry. + const GeoLib::GeoObject* getGEOObject(const std::string &geo_name, + GeoLib::GEOTYPE type, + const std::string &obj_name) const; /** constructor */ GEOObjects(); @@ -226,7 +269,6 @@ protected: /** vector manages pointers to SurfaceVec objects */ std::vector<SurfaceVec*> _sfc_vecs; }; - } // end namespace #endif /* GEOOBJECTS_H_ */ diff --git a/GeoLib/Station.cpp b/GeoLib/Station.cpp index 3a6bb42d6b4..9f3ad4a9e29 100644 --- a/GeoLib/Station.cpp +++ b/GeoLib/Station.cpp @@ -3,36 +3,44 @@ * KR Initial implementation */ +#include <cmath> #include <cstdlib> #include <fstream> #include <iomanip> -#include <cmath> // Base -#include "StringTools.h" #include "DateTools.h" +#include "StringTools.h" // GeoLib #include "Station.h" +namespace GeoLib +{ +Station::Station(double x, double y, double z, std::string name) : + Point (x,y,z), _name(name), _type(Station::STATION), _station_value(0.0) +{ + addProperty("x", &getX, &Station::setX); + addProperty("y", &getY, &Station::setY); + addProperty("z", &getZ, &Station::setZ); +} -namespace GeoLib { - -Station::Station(double x, double y, double z, std::string name, Color* const color) : - Point (x,y,z), _name(name), _type(Station::STATION), _color(color) +Station::Station(Point* coords, std::string name) : + Point (*coords), _name(name), _type(Station::STATION), _station_value(0.0) { addProperty("x", &getX, &Station::setX); addProperty("y", &getY, &Station::setY); addProperty("z", &getZ, &Station::setZ); } -Station::Station(Point* coords, std::string name, Color* const color) : - Point (*coords), _name(name), _type(Station::STATION), _color(color) +Station::Station(Station const& src) : + Point(src.getCoords()), _name(src._name), _type(src._type), + _station_value(src._station_value) { addProperty("x", &getX, &Station::setX); addProperty("y", &getY, &Station::setY); addProperty("z", &getZ, &Station::setZ); } -void Station::addProperty(std::string pname, double (*getFct)(void*), void (*set)(void*, double)) +void Station::addProperty(std::string pname, double (* getFct)(void*), void (* set)(void*, double)) { STNProperty p; p.name = pname; @@ -41,24 +49,8 @@ void Station::addProperty(std::string pname, double (*getFct)(void*), void (*set _properties.push_back(p); } - Station::~Station() { - delete _color; -} - -void Station::setColor(unsigned char r, unsigned char g, unsigned char b) -{ - (*_color)[0]=r; - (*_color)[1]=g; - (*_color)[2]=b; -} - -void Station::setColor(const Color* const color) -{ - (*_color)[0]=(*color)[0]; - (*_color)[1]=(*color)[1]; - (*_color)[2]=(*color)[2]; } Station* Station::createStation(const std::string & line) @@ -67,16 +59,14 @@ Station* Station::createStation(const std::string & line) Station* station = new Station(); std::list<std::string> fields = splitString(line, '\t'); - if (fields.size() >= 3) { - + if (fields.size() >= 3) + { it = fields.begin(); station->_name = *it; (*station)[0] = strtod((replaceString(",", ".", *(++it))).c_str(), NULL); (*station)[1] = strtod((replaceString(",", ".", *(++it))).c_str(), NULL); if (++it != fields.end()) - { (*station)[2] = strtod((replaceString(",", ".", *it)).c_str(), NULL); - } } else { @@ -85,7 +75,6 @@ Station* Station::createStation(const std::string & line) return NULL; } return station; - } Station* Station::createStation(const std::string &name, double x, double y, double z) @@ -102,9 +91,9 @@ const std::map<std::string, double> Station::getProperties() { std::map<std::string, double> propertyMap; - for (int i=0; i<static_cast<int>(_properties.size()); i++) + for (int i = 0; i < static_cast<int>(_properties.size()); i++) { - double (*getFct)(void*) = _properties[i].get; + double (* getFct)(void*) = _properties[i].get; //setFct set = _properties[i].set; propertyMap[_properties[i].name] = (*getFct)((void*)this); } @@ -115,23 +104,20 @@ const std::map<std::string, double> Station::getProperties() bool Station::inSelection(const std::vector<PropertyBounds> &bounds) { double value; - for (size_t i=0; i<bounds.size(); i++) + for (size_t i = 0; i < bounds.size(); i++) { - for (size_t j=0; j<_properties.size(); j++) - { - if (_properties[j].name.compare(bounds[i].getName())==0) + for (size_t j = 0; j < _properties.size(); j++) + if (_properties[j].name.compare(bounds[i].getName()) == 0) { - double (*get)(void*) = _properties[j].get; + double (* get)(void*) = _properties[j].get; value = (*get)((void*)this); - if (!(value >= bounds[i].getMin() && value <= bounds[i].getMax())) return false; + if (!(value >= bounds[i].getMin() && value <= bounds[i].getMax())) + return false; } - } } return true; } - - //////////////////////// // The Borehole class // //////////////////////// @@ -152,27 +138,29 @@ StationBorehole::~StationBorehole(void) { // deletes profile vector of borehole, starting at layer 1 // the first point is NOT deleted as it points to the station object itself - for (size_t k(1); k<_profilePntVec.size(); k++) delete _profilePntVec[k]; + for (size_t k(1); k < _profilePntVec.size(); k++) + delete _profilePntVec[k]; } int StationBorehole::find(const std::string &str) { size_t size = _soilName.size(); - for (size_t i=0; i<size; i++) - { - if (_soilName[i].find(str)==0) return 1; - } + for (size_t i = 0; i < size; i++) + if (_soilName[i].find(str) == 0) + return 1; return 0; } -int StationBorehole::readStratigraphyFile(const std::string &path, std::vector<std::list<std::string> > &data) +int StationBorehole::readStratigraphyFile(const std::string &path, + std::vector<std::list<std::string> > &data) { - std::string line; + std::string line; std::ifstream in( path.c_str() ); if (!in.is_open()) - { - std::cout << "StationBorehole::readStratigraphyFile() - Could not open file..." << std::endl; + { + std::cout << "StationBorehole::readStratigraphyFile() - Could not open file..." << + std::endl; return 0; } @@ -193,29 +181,27 @@ int StationBorehole::addStratigraphy(const std::string &path, StationBorehole* b if (readStratigraphyFile(path, data)) { size_t size = data.size(); - for (size_t i=0; i<size; i++) + for (size_t i = 0; i < size; i++) addLayer(data[i], borehole); // check if a layer is missing size = borehole->_soilName.size(); std::cout << "StationBorehole::addStratigraphy ToDo" << std::endl; - // for (size_t i=0; i<size; i++) - // { - // if ((borehole->_soilLayerThickness[i] == -1) ||(borehole->_soilName[i].compare("") == 0)) - // { - // borehole->_soilLayerThickness.clear(); - // borehole->_soilName.clear(); - // - // cout << "StationBorehole::addStratigraphy() - Profile incomplete (Borehole " << borehole->_name << ", Layer " << (i+1) << " missing).\n"; - // - // return 0; - // } - // } + // for (size_t i=0; i<size; i++) + // { + // if ((borehole->_soilLayerThickness[i] == -1) ||(borehole->_soilName[i].compare("") == 0)) + // { + // borehole->_soilLayerThickness.clear(); + // borehole->_soilName.clear(); + // + // cout << "StationBorehole::addStratigraphy() - Profile incomplete (Borehole " << borehole->_name << ", Layer " << (i+1) << " missing).\n"; + // + // return 0; + // } + // } } else - { borehole->addSoilLayer(borehole->getDepth(), "depth"); - } return 1; } @@ -231,21 +217,42 @@ int StationBorehole::addLayer(std::list<std::string> fields, StationBorehole* bo // int layer = atoi(fields.front().c_str()); fields.pop_front(); - std::cerr << "StationBorehole::addLayer - assuming correct order" << std::endl; + std::cerr << "StationBorehole::addLayer - assuming correct order" << + std::endl; double thickness(strtod(replaceString(",", ".", fields.front()).c_str(), 0)); fields.pop_front(); borehole->addSoilLayer(thickness, fields.front()); } - } else { + } + else + { std::cout - << "StationBorehole::addLayer() - Unexpected file format (Borehole " - << borehole->_name << ")..." << std::endl; + << "StationBorehole::addLayer() - Unexpected file format (Borehole " + << borehole->_name << ")..." << std::endl; return 0; } return 1; } -int StationBorehole::addStratigraphies(const std::string &path, std::vector<Point*> *boreholes) +int StationBorehole::addStratigraphy(const std::vector<GeoLib::Point*> &profile, const std::vector<std::string> soil_names) +{ + if (((profile.size()-1) == soil_names.size()) && (soil_names.size()>0)) + { + this->_profilePntVec.push_back(profile[0]); + size_t nLayers = soil_names.size(); + for (size_t i=0; i<nLayers; i++) + { + this->_profilePntVec.push_back(profile[i+1]); + this->_soilName.push_back(soil_names[i]); + } + return 1; + } + + std::cout << "Error in StationBorehole::addStratigraphy() - Length of parameter vectors does not match." << std::endl; + return 0; +} + +int StationBorehole::addStratigraphies(const std::string &path, std::vector<Point*>* boreholes) { std::vector<std::list<std::string> > data; @@ -253,47 +260,51 @@ int StationBorehole::addStratigraphies(const std::string &path, std::vector<Poin { std::string name; - size_t it=0; + size_t it = 0; size_t nBoreholes = data.size(); - for (size_t i=0; i<nBoreholes; i++) { + for (size_t i = 0; i < nBoreholes; i++) + { std::list<std::string> fields = data[i]; - if (fields.size() >= 4) { + if (fields.size() >= 4) + { name = static_cast<StationBorehole*>((*boreholes)[it])->_name; - if ( fields.front().compare(name) != 0 ) { - if (it < boreholes->size()-1) it++; - } + if ( fields.front().compare(name) != 0 ) + if (it < boreholes->size() - 1) + it++; fields.pop_front(); //the method just assumes that layers are read in correct order fields.pop_front(); - double thickness (strtod(replaceString(",", ".", fields.front()).c_str(), 0)); + double thickness (strtod(replaceString(",", ".", + fields.front()).c_str(), 0)); fields.pop_front(); std::string soil_name (fields.front()); fields.pop_front(); - static_cast<StationBorehole*>((*boreholes)[it])->addSoilLayer(thickness, soil_name); - } else - { - std::cout << "StationBorehole::addStratigraphies() - Unexpected file format..." << std::endl; - //return 0; + static_cast<StationBorehole*>((*boreholes)[it])->addSoilLayer( + thickness, + soil_name); } + else + std::cout << + "StationBorehole::addStratigraphies() - Unexpected file format..." + << std::endl; + //return 0; } } else - { createSurrogateStratigraphies(boreholes); - } return 1; } - StationBorehole* StationBorehole::createStation(const std::string &line) { StationBorehole* borehole = new StationBorehole(); std::list<std::string> fields = splitString(line, '\t'); - if (fields.size() >= 5) { + if (fields.size() >= 5) + { borehole->_name = fields.front(); fields.pop_front(); (*borehole)[0] = strtod((replaceString(",", ".", fields.front())).c_str(), NULL); @@ -302,7 +313,7 @@ StationBorehole* StationBorehole::createStation(const std::string &line) fields.pop_front(); (*borehole)[2] = strtod((replaceString(",", ".", fields.front())).c_str(), NULL); fields.pop_front(); - borehole->_depth = strtod((replaceString(",", ".", fields.front())).c_str(), NULL); + borehole->_depth = strtod((replaceString(",", ".", fields.front())).c_str(), NULL); fields.pop_front(); if (fields.empty()) borehole->_date = 0; @@ -321,7 +332,12 @@ StationBorehole* StationBorehole::createStation(const std::string &line) return borehole; } -StationBorehole* StationBorehole::createStation(const std::string &name, double x, double y, double z, double depth, std::string date) +StationBorehole* StationBorehole::createStation(const std::string &name, + double x, + double y, + double z, + double depth, + std::string date) { StationBorehole* station = new StationBorehole(); station->_name = name; @@ -329,14 +345,15 @@ StationBorehole* StationBorehole::createStation(const std::string &name, double (*station)[1] = y; (*station)[2] = z; station->_depth = depth; - if (date.compare("0000-00-00")) station->_date = BaseLib::xmlDate2double(date); + if (date.compare("0000-00-00") != 0) + station->_date = BaseLib::xmlDate2double(date); return station; } -void StationBorehole::createSurrogateStratigraphies(std::vector<Point*> *boreholes) +void StationBorehole::createSurrogateStratigraphies(std::vector<Point*>* boreholes) { size_t nBoreholes = boreholes->size(); - for (size_t i=0; i<nBoreholes; i++) + for (size_t i = 0; i < nBoreholes; i++) { StationBorehole* bore = static_cast<StationBorehole*>((*boreholes)[i]); bore->addSoilLayer(bore->getDepth(), "depth"); @@ -346,29 +363,28 @@ void StationBorehole::createSurrogateStratigraphies(std::vector<Point*> *borehol void StationBorehole::addSoilLayer ( double thickness, const std::string &soil_name) { /* - // TF - Altmark - if (_profilePntVec.empty()) - addSoilLayer ((*this)[0], (*this)[1], (*this)[2]-thickness, soil_name); - else { - size_t idx (_profilePntVec.size()); - // read coordinates from last above - double x((*_profilePntVec[idx-1])[0]); - double y((*_profilePntVec[idx-1])[1]); - double z((*_profilePntVec[idx-1])[2]-thickness); - addSoilLayer (x, y, z, soil_name); - } - */ + // TF - Altmark + if (_profilePntVec.empty()) + addSoilLayer ((*this)[0], (*this)[1], (*this)[2]-thickness, soil_name); + else { + size_t idx (_profilePntVec.size()); + // read coordinates from last above + double x((*_profilePntVec[idx-1])[0]); + double y((*_profilePntVec[idx-1])[1]); + double z((*_profilePntVec[idx-1])[2]-thickness); + addSoilLayer (x, y, z, soil_name); + } + */ // KR - Bode if (_profilePntVec.empty()) addSoilLayer ((*this)[0], (*this)[1], (*this)[2], ""); size_t idx (_profilePntVec.size()); - double x((*_profilePntVec[idx-1])[0]); - double y((*_profilePntVec[idx-1])[1]); - double z((*_profilePntVec[0])[2]-thickness); + double x((*_profilePntVec[idx - 1])[0]); + double y((*_profilePntVec[idx - 1])[1]); + double z((*_profilePntVec[0])[2] - thickness); addSoilLayer (x, y, z, soil_name); - } void StationBorehole::addSoilLayer ( double x, double y, double z, const std::string &soil_name) @@ -376,5 +392,4 @@ void StationBorehole::addSoilLayer ( double x, double y, double z, const std::st _profilePntVec.push_back (new Point (x, y, z)); _soilName.push_back(soil_name); } - } // namespace diff --git a/GeoLib/Station.h b/GeoLib/Station.h index 991a4e81e8d..032695a5f06 100644 --- a/GeoLib/Station.h +++ b/GeoLib/Station.h @@ -6,19 +6,18 @@ #ifndef GEO_STATION_H #define GEO_STATION_H -#include <string> #include <list> -#include <vector> #include <map> +#include <string> +#include <vector> -#include "Polyline.h" -#include "Point.h" #include "Color.h" +#include "Point.h" +#include "Polyline.h" #include "PropertyBounds.h" - -namespace GeoLib { - +namespace GeoLib +{ /** * \ingroup GeoLib * @@ -41,22 +40,21 @@ namespace GeoLib { */ class Station : public Point { - protected: //typedef double (Station::*getFct)(); //typedef void (Station::*setFct)(double); /** - * \brief Container for station-properties. + * \brief Container for station-properties. * Each property consists of a name, a get- and a set-function. * Please refer to Station::addProperty for details. */ struct STNProperty { std::string name; - double (*get)(void*); - void (*set)(void*, double); + double (* get)(void*); + void (* set)(void*, double); }; public: @@ -77,10 +75,19 @@ public: * \param name The name of the station. * \param color The color of the station in visualisation. */ - Station(double x = 0.0, double y = 0.0, double z = 0.0, std::string name = "", Color* const color = new Color(0,128,0)); + Station(double x = 0.0, + double y = 0.0, + double z = 0.0, + std::string name = ""); - Station(Point* coords, std::string name = "", Color* const color = new Color(0,128,0)); + Station(Point* coords, std::string name = ""); + /** + * Constructor copies the source object + * @param src the Station object that should be copied + * @return + */ + Station(Station const& src); virtual ~Station(); @@ -102,16 +109,7 @@ public: * \param set A function pointer to a static write function for the variable referred to by pname * \return */ - void addProperty(std::string pname, double (*get)(void*), void (*set)(void*, double)); - - /// Sets colour for this station - void setColor(unsigned char r, unsigned char g, unsigned char b); - - /// Sets colour for this station - void setColor(const Color* color); - - /// returns the colour for this station - Color* getColor () { return _color; } + void addProperty(std::string pname, double (* get)(void*), void (* set)(void*, double)); /// Returns a map containing all the properties of that station type. const std::map<std::string, double> getProperties(); @@ -123,7 +121,7 @@ public: bool inSelection(std::map<std::string, double> properties) const; /// Returns the name of the station. - std::string getName() const { return _name; } + std::string const& getName() const { return _name; } /// Returns the GeoSys-station-type for the station. int type() const { return _type; } @@ -134,6 +132,9 @@ public: /// Creates a new station object based on the given parameters. static Station* createStation(const std::string &name, double x, double y, double z); + double getStationValue() { return this->_station_value; }; + + void setStationValue(double station_value) { this->_station_value = station_value; }; protected: /** @@ -148,32 +149,34 @@ protected: * \param stnObject A pointer to the station object for which the x-coordinate should be returned, usually (void*)this will work fine. * \return The x-coordinate for this station. */ - static double getX(void* stnObject) { Station* stn = (Station*)stnObject; return (*stn)[0]; } + static double getX(void* stnObject) { Station* stn = (Station*)stnObject; + return (*stn)[0]; } /// Returns the y-coordinate of this station. See the detailed documentation for getX concerning the syntax. - static double getY(void* stnObject) { Station* stn = (Station*)stnObject; return (*stn)[1]; } + static double getY(void* stnObject) { Station* stn = (Station*)stnObject; + return (*stn)[1]; } /// Returns the z-coordinate of this station. See the detailed documentation for getX concerning the syntax. - static double getZ(void* stnObject) { Station* stn = (Station*)stnObject; return (*stn)[2]; } + static double getZ(void* stnObject) { Station* stn = (Station*)stnObject; + return (*stn)[2]; } /// Sets the x-coordinate for this station. See the detailed documentation for getX concerning the syntax. - static void setX(void* stnObject, double val) { Station* stn = (Station*)stnObject; (*stn)[0]=val; } + static void setX(void* stnObject, double val) { Station* stn = (Station*)stnObject; + (*stn)[0] = val; } /// Sets the y-coordinate for this station. See the detailed documentation for getX concerning the syntax. - static void setY(void* stnObject, double val) { Station* stn = (Station*)stnObject; (*stn)[1]=val; } + static void setY(void* stnObject, double val) { Station* stn = (Station*)stnObject; + (*stn)[1] = val; } /// Sets the z-coordinate for this station. See the detailed documentation for getX concerning the syntax. - static void setZ(void* stnObject, double val) { Station* stn = (Station*)stnObject; (*stn)[2]=val; } - + static void setZ(void* stnObject, double val) { Station* stn = (Station*)stnObject; + (*stn)[2] = val; } std::string _name; - StationType _type; // GeoSys Station Type + StationType _type; // GeoSys Station Type std::vector<STNProperty> _properties; - private: - Color* _color; + double _station_value; }; - /********* Boreholes *********/ - /** * \brief A borehole as a geometric object. * @@ -181,7 +184,6 @@ private: */ class StationBorehole : public Station { - public: /** constructor initialises the borehole with the given coordinates */ StationBorehole(double x = 0.0, double y = 0.0, double z = 0.0); @@ -191,7 +193,15 @@ public: static StationBorehole* createStation(const std::string &line); /// Creates a new borehole object based on the given parameters. - static StationBorehole* createStation(const std::string &name, double x, double y, double z, double depth, std::string date = ""); + static StationBorehole* createStation(const std::string &name, + double x, + double y, + double z, + double depth, + std::string date = ""); + + /// Adds a stratigraphy to a borehole given a vector of points of length "n" and a vector of soil names of length "n-1". + int addStratigraphy(const std::vector<GeoLib::Point*> &profile, const std::vector<std::string> soil_names); /// Reads the stratigraphy for a specified station from a file static int addStratigraphy(const std::string &path, StationBorehole* borehole); @@ -203,7 +213,7 @@ public: * Be very careful when using this method -- it is pretty fast but it checks nothing and just * assumes that everything is in right order and will work out fine! */ - static int addStratigraphies(const std::string &path, std::vector<Point*> *boreholes); + static int addStratigraphies(const std::string &path, std::vector<Point*>* boreholes); /// Finds the given string in the vector of soil-names int find(const std::string &str); @@ -236,33 +246,40 @@ public: */ void addSoilLayer ( double x, double y, double z, const std::string &soil_name); - - protected: /// Returns the depth of this borehole. Please see the documentation for Station::getX for details concerning the syntax. - static double getDepth(void* stnObject) { StationBorehole* stn = (StationBorehole*)stnObject; return stn->_depth; } + static double getDepth(void* stnObject) { StationBorehole* stn = + (StationBorehole*)stnObject; + return stn->_depth; } /// Returns the date this borehole has been drilled. Please see the documentation for Station::getX for details concerning the syntax. - static double getDate(void* stnObject) { StationBorehole* stn = (StationBorehole*)stnObject; return stn->_date; } + static double getDate(void* stnObject) { StationBorehole* stn = + (StationBorehole*)stnObject; + return stn->_date; } /// Sets the depth of this borehole. Please see the documentation for Station::getX for details concerning the syntax. - static void setDepth(void* stnObject, double val) { StationBorehole* stn = (StationBorehole*)stnObject; stn->_depth = val; } + static void setDepth(void* stnObject, double val) { StationBorehole* stn = + (StationBorehole*)stnObject; + stn->_depth = val; } /// Sets the date when this borehole has been drilled. Please see the documentation for Station::getX for details concerning the syntax. - static void setDate(void* stnObject, double val) { StationBorehole* stn = (StationBorehole*)stnObject; stn->_date = val; } + static void setDate(void* stnObject, double val) { StationBorehole* stn = + (StationBorehole*)stnObject; + stn->_date = val; } private: /// Adds a layer for the specified borehole profile based on the information given in the stringlist static int addLayer(std::list<std::string> fields, StationBorehole* borehole); /// Creates fake stratigraphies of only one layer with a thickness equal to the borehole depth - static void createSurrogateStratigraphies(std::vector<Point*> *boreholes); + static void createSurrogateStratigraphies(std::vector<Point*>* boreholes); /// Reads the specified file containing borehole stratigraphies into an vector of stringlists - static int readStratigraphyFile(const std::string &path, std::vector<std::list<std::string> > &data); + static int readStratigraphyFile(const std::string &path, + std::vector<std::list<std::string> > &data); //long profile_type; //std::vector<long> _soilType; double _zCoord; // height at which the borehole officially begins (this might _not_ be the actual elevation) - double _depth; // depth of the borehole - double _date; // date when the borehole has been drilled + double _depth; // depth of the borehole + double _date; // date when the borehole has been drilled /// Contains the names for all the soil layers std::vector<std::string> _soilName; @@ -270,7 +287,6 @@ private: /// Contains the points for the lower boundaries of all layers std::vector<Point*> _profilePntVec; }; - } // namespace #endif // GEO_STATION_H diff --git a/OGS/CMakeLists.txt b/OGS/CMakeLists.txt new file mode 100644 index 00000000000..cf0b709196d --- /dev/null +++ b/OGS/CMakeLists.txt @@ -0,0 +1,23 @@ +# Source files +GET_SOURCE_FILES(SOURCES_OGSLIB) +SET ( SOURCES ${SOURCES_OGSLIB}) + +# Create the library +ADD_LIBRARY(OgsLib STATIC ${SOURCES}) + +include_directories( + . + ${CMAKE_SOURCE_DIR}/BaseLib + ${CMAKE_SOURCE_DIR}/FemLib + ${CMAKE_SOURCE_DIR}/GeoLib + ${CMAKE_SOURCE_DIR}/MeshLib +) + + +target_link_libraries (OgsLib + BaseLib + FemLib + GeoLib + MeshLib +) + diff --git a/OGS/ProjectData.cpp b/OGS/ProjectData.cpp new file mode 100644 index 00000000000..7eb5d58c016 --- /dev/null +++ b/OGS/ProjectData.cpp @@ -0,0 +1,210 @@ +/** + * \file ProjectData.cpp + * 25/08/2010 KR Initial implementation + */ + +#include "ProjectData.h" +#include "StringTools.h" + +ProjectData::ProjectData() +: _geoObjects (NULL) +{} + +ProjectData::~ProjectData() +{ + delete _geoObjects; + for (std::map<std::string, MeshLib::CFEMesh*>::iterator it = _msh_vec.begin(); + it != _msh_vec.end(); ++it) + delete it->second; + size_t nCond (_cond_vec.size()); + for (size_t i = 0; i < nCond; i++) + delete _cond_vec[i]; +} + +void ProjectData::addMesh(MeshLib::CFEMesh* mesh, std::string &name) +{ + isUniqueMeshName(name); + _msh_vec[name] = mesh; +} + +const MeshLib::CFEMesh* ProjectData::getMesh(const std::string &name) const +{ + return _msh_vec.find(name)->second; +} + +bool ProjectData::removeMesh(const std::string &name) +{ + delete _msh_vec[name]; + size_t result = _msh_vec.erase(name); + return result > 0; +} + +bool ProjectData::meshExists(const std::string &name) +{ + if (_msh_vec.count(name)>0) return true; + return false; +} + +void ProjectData::addProcess(ProcessInfo* pcs) +{ + for (std::vector<ProcessInfo*>::const_iterator it = _pcs_vec.begin(); it != _pcs_vec.end(); ++it) + if ((*it)->getProcessType() == pcs->getProcessType()) + { + std::cout << "Error in ProjectData::addProcess() - " + << FiniteElement::convertProcessTypeToString(pcs->getProcessType()) << " process already exists." << std::endl; + } + + _pcs_vec.push_back(pcs); +} + +const ProcessInfo* ProjectData::getProcess(FiniteElement::ProcessType type) const +{ + for (std::vector<ProcessInfo*>::const_iterator it = _pcs_vec.begin(); it != _pcs_vec.end(); ++it) + if ((*it)->getProcessType() == type) + return *it; + + std::cout << "Error in ProjectData::getProcess() - No " + << FiniteElement::convertProcessTypeToString(type) << " process found..." << std::endl; + return NULL; +} + +bool ProjectData::removeProcess(FiniteElement::ProcessType type) +{ + for (std::vector<ProcessInfo*>::iterator it = _pcs_vec.begin(); it != _pcs_vec.end(); ++it) + if ((*it)->getProcessType() == type) + { + + delete *it; + _pcs_vec.erase(it); + return true; + } + + std::cout << "Error in ProjectData::removeProcess() - No " + << FiniteElement::convertProcessTypeToString(type) << " process found..." << std::endl; + return false; +} + +void ProjectData::addCondition(FEMCondition* cond) +{ + _cond_vec.push_back(cond); +} + +void ProjectData::addConditions(std::vector<FEMCondition*> conds) +{ + for (size_t i = 0; i < conds.size(); i++) + _cond_vec.push_back(conds[i]); +} + +const FEMCondition* ProjectData::getCondition(const std::string &geo_name, + GeoLib::GEOTYPE type, + const std::string &cond_name) const +{ + for (std::vector<FEMCondition*>::const_iterator it = _cond_vec.begin(); it != _cond_vec.end(); ++it) + if ((*it)->getAssociatedGeometryName().compare(geo_name) == 0) + if ( ((*it)->getGeoName().compare(cond_name) == 0) && + ((*it)->getGeoType() == type) ) + return *it; + + std::cout << "Error in ProjectData::getCondition() - No condition found with name \"" << + cond_name << "\"..." << std::endl; + return NULL; +} + +const std::vector<FEMCondition*> ProjectData::getConditions(FiniteElement::ProcessType pcs_type, + std::string geo_name, + FEMCondition::CondType cond_type) const +{ + // if all + if (pcs_type == FiniteElement::INVALID_PROCESS && geo_name.empty() && cond_type == FEMCondition::UNSPECIFIED) + return _cond_vec; + + // else: filter according to parameters + std::vector<FEMCondition*> conds; + for (std::vector<FEMCondition*>::const_iterator it = _cond_vec.begin(); it != _cond_vec.end(); ++it) + { + if ( ((pcs_type == FiniteElement::INVALID_PROCESS) || (pcs_type == ((*it)->getProcessType()))) && + ((geo_name.empty() || ((*it)->getAssociatedGeometryName().compare(geo_name) == 0))) && + ((cond_type == FEMCondition::UNSPECIFIED) || ((*it)->getCondType() == cond_type)) ) + conds.push_back(*it); + } + + return conds; +} + +void ProjectData::removeConditions(FiniteElement::ProcessType pcs_type, std::string geo_name, FEMCondition::CondType cond_type) +{ + // if all + if (pcs_type == FiniteElement::INVALID_PROCESS && geo_name.empty() && cond_type == FEMCondition::UNSPECIFIED) + { + for (size_t i=0; i<_cond_vec.size(); i++) delete _cond_vec[i]; + return; + } + + // else: filter according to parameters + for (std::vector<FEMCondition*>::iterator it = _cond_vec.begin(); it != _cond_vec.end(); ) + { + if ( ((pcs_type == FiniteElement::INVALID_PROCESS) || (pcs_type == ((*it)->getProcessType()))) && + ((geo_name.empty() || ((*it)->getAssociatedGeometryName().compare(geo_name) == 0))) && + ((cond_type == FEMCondition::UNSPECIFIED) || ((*it)->getCondType() == cond_type)) ) + { + delete *it; + it = _cond_vec.erase(it); + } + else + ++it; + } +} + +bool ProjectData::removeCondition(const std::string &geo_name, + GeoLib::GEOTYPE type, + const std::string &cond_name) +{ + for (std::vector<FEMCondition*>::iterator it = _cond_vec.begin(); it != _cond_vec.end(); ++it) + { + if ((*it)->getAssociatedGeometryName().compare(geo_name) == 0) + if ( ((*it)->getGeoName().compare(cond_name) == 0) && + ((*it)->getGeoType() == type) ) + { + delete *it; + _cond_vec.erase(it); + return true; + } + } + std::cout << "Error in ProjectData::removeCondition() - No condition found with name \"" << + cond_name << "\"..." << std::endl; + return false; +} + +bool ProjectData::isUniqueMeshName(std::string &name) +{ + int count(0); + bool isUnique(false); + std::string cpName; + + while (!isUnique) + { + isUnique = true; + cpName = name; + + count++; + // If the original name already exists we start to add numbers to name for + // as long as it takes to make the name unique. + if (count > 1) + cpName = cpName + "-" + number2str(count); + + for (std::map<std::string, MeshLib::CFEMesh*>::iterator it = _msh_vec.begin(); + it != _msh_vec.end(); ++it) + if ( cpName.compare(it->first) == 0 ) + isUnique = false; + } + + // At this point cpName is a unique name and isUnique is true. + // If cpName is not the original name, "name" is changed and isUnique is set to false, + // indicating that a vector with the original name already exists. + if (count > 1) + { + isUnique = false; + name = cpName; + } + return isUnique; +} diff --git a/OGS/ProjectData.h b/OGS/ProjectData.h new file mode 100644 index 00000000000..7ccd75bb71d --- /dev/null +++ b/OGS/ProjectData.h @@ -0,0 +1,103 @@ +/** + * \file ProjectData.h + * 25/08/2010 KR Initial implementation + */ + +#ifndef PROJECTDATA_H_ +#define PROJECTDATA_H_ + +#include "FEMCondition.h" +#include "FEMEnums.h" +#include "GEOObjects.h" +#include "Mesh.h" + +/** + * The ProjectData Object contains all the data needed for a certain project, i.e. all + * geometric data (stored in a GEOObjects-object), all the meshes, FEM Conditions (i.e. + * Boundary Conditions, Source Terms and Initial Conditions), etc. + * ProjectData does not administrate any of the objects, it is just a "container class" + * to store them all in one place. + * For each class of object stored in this container exists an add-, get- and remove-method. + * + * \sa GEOModels, FEMCondition + */ +class ProjectData +{ +public: + ProjectData(); + virtual ~ProjectData(); + + //** Geometry functionality **// + + // Returns the GEOObjects containing all points, polylines and surfaces + GeoLib::GEOObjects* getGEOObjects() { return _geoObjects; } + + // Returns the GEOObjects containing all points, polylines and surfaces + void setGEOObjects(GeoLib::GEOObjects* geo_objects) { _geoObjects = geo_objects; } + + //** Mesh functionality **// + + /// Adds a new mesh + virtual void addMesh(MeshLib::Mesh* mesh, std::string &name); + + /// Returns the mesh with the given name. + const MeshLib::Mesh* getMesh(const std::string &name) const; + + /// Returns all the meshes with their respective names + const std::map<std::string, MeshLib::Mesh*>& getMeshObjects() const { return _msh_vec; } + + /// Removes the mesh with the given name. + virtual bool removeMesh(const std::string &name); + + /// Checks if the name of the mesh is already exists, if so it generates a unique name. + bool isUniqueMeshName(std::string &name); + + bool meshExists(const std::string &name); + + //** Process functionality **// + + /// Adds a new process + virtual void addProcess(ProcessInfo* pcs); + + /// Returns a process of the given type + const ProcessInfo* getProcess(FiniteElement::ProcessType type) const; + + /// Removes a process of the given type + virtual bool removeProcess(FiniteElement::ProcessType type); + + //** FEM Condition functionality **// + + /// Adds a new FEM Condition + virtual void addCondition(FEMCondition* cond); + + /// Adds new FEM Conditions + virtual void addConditions(std::vector<FEMCondition*> conds); + + /// Returns the FEM Condition set on a GeoObject with the given name and type from a certain geometry. + const FEMCondition* getCondition(const std::string &geo_name, + GeoLib::GEOTYPE type, + const std::string &cond_name) const; + + /// Returns all FEM Conditions with the given type from a certain geometry. + const std::vector<FEMCondition*> getConditions(FiniteElement::ProcessType pcs_type = FiniteElement::INVALID_PROCESS, + std::string geo_name = "", + FEMCondition::CondType type = FEMCondition::UNSPECIFIED) const; + + /// Removes the FEM Condition set on a GeoObject with the given name and type from a certain geometry. + virtual bool removeCondition(const std::string &geo_name, + GeoLib::GEOTYPE type, + const std::string &cond_name); + + /// Removes all FEM Conditions with the given type from the given process + virtual void removeConditions(FiniteElement::ProcessType pcs_type = FiniteElement::INVALID_PROCESS, + std::string geo_name = "", + FEMCondition::CondType cond_type = FEMCondition::UNSPECIFIED); + +private: + GeoLib::GEOObjects* _geoObjects; + std::map<std::string, MeshLib::Mesh*> _msh_vec; + std::vector<ProcessInfo*> _pcs_vec; + std::vector<FEMCondition*> _cond_vec; +}; + +#endif //PROJECTDATA_H_ -- GitLab