WSL/SLF GitLab Repository

Commit ba0b7d3e authored by Mathias Bavay's avatar Mathias Bavay
Browse files

In order to implement an efficient and portable object serialization, it has...

In order to implement an efficient and portable object serialization, it has been decided that all serializable objects would be manually serialized to an std::iostream. Then, the parallelization framework (mpi, popc, etc) can take over this stream and move it to another node. Therefore, the operators "<<" and ">>" are now reserved for serialization (as seems to be standard) and the debug outputs are obtained by printing "object.toString()". This means that all debug code has potentially to be fixed, by replacing "std::cout << object" by "std::cout << object.toString()".
parent 19910905
......@@ -14,11 +14,11 @@ int main(void) {
io.read2DGrid(grid2, MeteoGrids::TA, Date(2008, 12, 10, 12, 30, 0));
//debug style output
std::cout << "Initial air temperatures grid: " << grid2 << "\n";
std::cout << "Initial air temperatures grid: " << grid2.toString() << "\n";
//simple arithmetic operations (the nodata values are preserved)
grid2.grid2D -= 273.15;
std::cout << "Air temperatures grid in celsius: " << grid2 << "\n";
std::cout << "Air temperatures grid in celsius: " << grid2.toString() << "\n";
//operations between grids
Grid2DObject grid3(grid1.ncols, grid1.nrows, grid1.cellsize, grid1.llcorner);
......@@ -33,7 +33,7 @@ int main(void) {
//now let's make a grid subset: from point (2,2) and size 5x5
Grid2DObject subgrid(grid1, 2, 2, 5, 5);
std::cout << "The subgrid of grid1 is: " << subgrid << "\n";
std::cout << "The subgrid of grid1 is: " << subgrid.toString() << "\n";
//we can check if two grids are "compatible", having the same geolocalization
if(subgrid.isSameGeolocalization(grid1))
......
......@@ -16,13 +16,13 @@ int main(int /*argc*/, char** argv) {
m1.random(10.);
std::cout << "Randomly filled (" << n << "," << n << ") matrix\n";
std::cout << "\t\tm1=" << m1; //print the matrix on the screen
std::cout << "\t\tm1=" << m1.toString(); //print the matrix on the screen
std::cout << "=> det(m1)=" << m1.det() << "\n"; //determinant
std::cout << "\t\tT(m1)=" << m1.getT(); //transpose
std::cout << "\t\tm1-2=" << m1-2.; //arithmetic with scalars
std::cout << "\t\tm1*m1=" << m1*m1; //arithmetic with matrices
std::cout << "\t\tT(m1)=" << m1.getT().toString(); //transpose
std::cout << "\t\tm1-2=" << (m1-2.).toString(); //arithmetic with scalars
std::cout << "\t\tm1*m1=" << (m1*m1).toString(); //arithmetic with matrices
Matrix m2= m1.getInv();
std::cout << "\t\tinv(m1)=" << m2; //inverse
std::cout << "\t\tinv(m1)=" << m2.toString(); //inverse
Matrix m3=m1*m2;
if(m3.isIdentity()==true) //test if this is the identity matrix
std::cout << "=> m1*inv(m1) is identity matrix\n";
......@@ -31,13 +31,13 @@ int main(int /*argc*/, char** argv) {
Matrix I(n,1.); //build an n*n identity matrix
Matrix m4=Matrix::solve(m1,I); //solve m1*X=I
std::cout << "\tIn m1*X=I, X=" << m4; //print the matrix on the screen
std::cout << "\tIn m1*X=I, X=" << m4.toString(); //print the matrix on the screen
Matrix L,U;
if(m1.LU(L,U)==false) { //LU factorization
std::cout << "\tLU factorization of m1 can not be computed\n";
} else {
std::cout << "\tLU factorization of m1: L=" << L << "\t\tU=" << U;
std::cout << "\tLU factorization of m1: L=" << L.toString() << "\t\tU=" << U.toString();
}
return 0;
......
......@@ -22,7 +22,7 @@ int main(int /*argc*/, char** argv) {
//writing some data out in order to prove that it really worked!
for (unsigned int ii=0; ii < vecMeteo.size(); ii++) {
std::cout << "---------- Station: " << (ii+1) << " / " << vecMeteo.size() << std::endl;
std::cout << vecMeteo[ii] << std::endl;
std::cout << vecMeteo[ii].toString() << std::endl;
}
return 0;
......
......@@ -17,7 +17,7 @@ int main(int /*argc*/, char** argv) {
mio::IOUtils::convertString(iswr_ref,argv[2]); //get measured global incoming radiation
Sun.calculateRadiation(TA, RH, mean_albedo);
std::cout << Sun;
std::cout << Sun.toString();
//radiation in the beam
double B_toa, B_direct, B_diffuse;
......
......@@ -21,6 +21,7 @@
#include <vector>
#include <limits>
#include <iostream>
#include <iterator>
#include <meteoio/IOUtils.h>
#include <meteoio/IOExceptions.h>
......@@ -100,7 +101,9 @@ template<class T> class Array1D {
void abs();
template<class P> friend std::ostream& operator<<(std::ostream& os, const Array1D<P>& array);
const std::string toString() const;
template<class P> friend std::iostream& operator<<(std::iostream& os, const Array1D<P>& array);
template<class P> friend std::iostream& operator>>(std::iostream& is, Array1D<P>& array);
bool checkEpsilonEquality(const Array1D<double>& rhs, const double& epsilon) const;
static bool checkEpsilonEquality(const Array1D<double>& rhs1, const Array1D<double>& rhs2, const double& epsilon);
......@@ -229,15 +232,30 @@ template<class T> bool Array1D<T>::isEmpty() const {
return (nx==0);
}
template<class T> std::ostream& operator<<(std::ostream& os, const Array1D<T>& array) {
template<class T> const std::string Array1D<T>::toString() const {
std::stringstream os;
os << "<array1d>\n";
for(unsigned int ii=0; ii<array.nx; ii++) {
os << array(ii) << " ";
for(unsigned int ii=0; ii<nx; ii++) {
os << vecData[ii] << " ";
}
os << "\n</array1d>\n";
return os.str();
}
template<class P> std::iostream& operator<<(std::iostream& os, const Array1D<P>& array) {
os.write(reinterpret_cast<const char*>(&array.keep_nodata), sizeof(array.keep_nodata));
os.write(reinterpret_cast<const char*>(&array.nx), sizeof(array.nx));
os.write(reinterpret_cast<const char*>(&array.vecData[0]), array.nx*sizeof(P));
return os;
}
template<class P> std::iostream& operator>>(std::iostream& is, Array1D<P>& array) {
is.read(reinterpret_cast<char*>(&array.keep_nodata), sizeof(array.keep_nodata));
is.read(reinterpret_cast<char*>(&array.nx), sizeof(array.nx));
array.vecData.resize(array.nx);
is.read(reinterpret_cast<char*>(&array.vecData[0]), array.nx*sizeof(P)); //30 times faster than assign() or copy()
}
template<class T> void Array1D<T>::insertAt(const int& index, T e) {
if (index < 0) {
vecData.push_back(e);
......
......@@ -171,7 +171,9 @@ template<class T> class Array2D {
const Array2D<T> getAbs() const;
void abs();
template<class P> friend std::ostream& operator<<(std::ostream& os, const Array2D<P>& array);
const std::string toString() const;
template<class P> friend std::iostream& operator<<(std::iostream& os, const Array2D<P>& array);
template<class P> friend std::iostream& operator>>(std::iostream& is, Array2D<P>& array);
bool checkEpsilonEquality(const Array2D<double>& rhs, const double& epsilon) const;
static bool checkEpsilonEquality(const Array2D<double>& rhs1, const Array2D<double>& rhs2, const double& epsilon);
......@@ -377,19 +379,37 @@ template<class T> bool Array2D<T>::isEmpty() const {
return (nx==0 && ny==0);
}
template<class T> std::ostream& operator<<(std::ostream& os, const Array2D<T>& array) {
template<class T> const std::string Array2D<T>::toString() const {
std::stringstream os;
os << "<array2d>\n";
for(unsigned int jj=0; jj<array.ny; jj++) {
unsigned int jnx = jj*array.nx;
for (unsigned int ii=0; ii<array.nx; ii++) {
os << array(ii+jnx) << " ";
for(unsigned int jj=0; jj<ny; jj++) {
const unsigned int jnx = jj*nx;
for (unsigned int ii=0; ii<nx; ii++) {
os << vecData[ii+jnx] << " ";
}
os << "\n";
}
os << "</array2d>\n";
return os.str();
}
template<class P> std::iostream& operator<<(std::iostream& os, const Array2D<P>& array) {
os.write(reinterpret_cast<const char*>(&array.keep_nodata), sizeof(array.keep_nodata));
os.write(reinterpret_cast<const char*>(&array.nx), sizeof(array.nx));
os.write(reinterpret_cast<const char*>(&array.ny), sizeof(array.ny));
os.write(reinterpret_cast<const char*>(&array.vecData[0]), array.nx*array.ny*sizeof(P));
return os;
}
template<class P> std::iostream& operator>>(std::iostream& is, Array2D<P>& array) {
is.read(reinterpret_cast<char*>(&array.keep_nodata), sizeof(array.keep_nodata));
is.read(reinterpret_cast<char*>(&array.nx), sizeof(array.nx));
is.read(reinterpret_cast<char*>(&array.ny), sizeof(array.ny));
array.vecData.resize(array.nx*array.ny);
is.read(reinterpret_cast<char*>(&array.vecData[0]), array.nx*array.ny*sizeof(P)); //30 times faster than assign() or copy()
}
template<class T> T Array2D<T>::getMin() const {
T min = std::numeric_limits<T>::max();
......
......@@ -204,7 +204,9 @@ template<class T> class Array3D {
const Array3D<T> getAbs() const;
void abs();
template<class P> friend std::ostream& operator<<(std::ostream& os, const Array3D<P>& array);
const std::string toString() const;
template<class P> friend std::iostream& operator<<(std::iostream& os, const Array3D<P>& array);
template<class P> friend std::iostream& operator>>(std::iostream& is, Array3D<P>& array);
bool checkEpsilonEquality(const Array3D<double>& rhs, const double& epsilon) const;
static bool checkEpsilonEquality(const Array3D<double>& rhs1, const Array3D<double>& rhs2, const double& epsilon);
......@@ -436,21 +438,40 @@ template<class T> bool Array3D<T>::isEmpty() const {
return (nx==0 && ny==0 && nz==0);
}
template<class T> std::ostream& operator<<(std::ostream& os, const Array3D<T>& array) {
template<class T> const std::string Array3D<T>::toString() const {
std::stringstream os;
os << "<array3d>\n";
for (unsigned int kk=0; kk<array.nz; kk++) {
for (unsigned int kk=0; kk<nz; kk++) {
os << "depth[" << kk << "]\n";
for(unsigned int ii=0; ii<array.nx; ii++) {
for (unsigned int jj=0; jj<array.ny; jj++) {
os << array(ii,jj,kk) << " ";
for(unsigned int ii=0; ii<nx; ii++) {
for (unsigned int jj=0; jj<ny; jj++) {
os << operator()(ii,jj,kk) << " ";
}
os << "\n";
}
}
os << "</array3d>\n";
return os.str();
}
template<class P> std::iostream& operator<<(std::iostream& os, const Array3D<P>& array) {
os.write(reinterpret_cast<const char*>(&array.keep_nodata), sizeof(array.keep_nodata));
os.write(reinterpret_cast<const char*>(&array.nx), sizeof(array.nx));
os.write(reinterpret_cast<const char*>(&array.ny), sizeof(array.ny));
os.write(reinterpret_cast<const char*>(&array.nz), sizeof(array.nz));
os.write(reinterpret_cast<const char*>(&array.vecData[0]), array.nx*array.ny*array.nz*sizeof(P));
return os;
}
template<class P> std::iostream& operator>>(std::iostream& is, Array3D<P>& array) {
is.read(reinterpret_cast<char*>(&array.keep_nodata), sizeof(array.keep_nodata));
is.read(reinterpret_cast<char*>(&array.nx), sizeof(array.nx));
is.read(reinterpret_cast<char*>(&array.ny), sizeof(array.ny));
is.read(reinterpret_cast<char*>(&array.nz), sizeof(array.nz));
array.vecData.resize(array.nx*array.ny*array.nz);
is.read(reinterpret_cast<char*>(&array.vecData[0]), array.nx*array.ny*array.nz*sizeof(P)); //30 times faster than assign() or copy()
}
template<class T> T Array3D<T>::getMin() const {
T min = std::numeric_limits<T>::max();
......
......@@ -157,12 +157,13 @@ template<class T> class Array4D {
const Array4D<T> getAbs() const;
void abs();
//template<class P> friend std::ostream& operator<<(std::ostream& os, const Array4D<P>& array);
const std::string toString() const;
template<class P> friend std::iostream& operator<<(std::iostream& os, const Array4D<P>& array);
template<class P> friend std::iostream& operator>>(std::iostream& is, Array4D<P>& array);
bool checkEpsilonEquality(const Array4D<double>& rhs, const double& epsilon) const;
static bool checkEpsilonEquality(const Array4D<double>& rhs1, const Array4D<double>& rhs2, const double& epsilon);
T& operator ()(const unsigned int& i);
const T operator ()(const unsigned int& i) const;
T& operator ()(const unsigned int& w, const unsigned int& x, const unsigned int& y, const unsigned int& z);
......@@ -400,22 +401,45 @@ template<class T> bool Array4D<T>::isEmpty() const {
return (nw==0 && nx==0 && ny==0 && nz==0);
}
/*
template<class T> std::ostream& operator<<(std::ostream& os, const Array4D<T>& array) {
template<class T> const std::string Array4D<T>::toString() const {
std::stringstream os;
os << "<array4d>\n";
for (unsigned int kk=0; kk<array.nz; kk++) {
os << "depth[" << kk << "]\n";
for(unsigned int ii=0; ii<array.nx; ii++) {
for (unsigned int jj=0; jj<array.ny; jj++) {
os << array(ii,jj,kk) << " ";
for (unsigned int ll=0; ll<nw; ll++) {
os << "dim4[" << ll << "]\n";
for (unsigned int kk=0; kk<nz; kk++) {
os << "depth[" << kk << "]\n";
for(unsigned int ii=0; ii<nx; ii++) {
for (unsigned int jj=0; jj<ny; jj++) {
os << operator()(ii,jj,kk,ll) << " ";
}
os << "\n";
}
os << "\n";
}
}
os << "</array4d>\n";
return os.str();
}
template<class P> std::iostream& operator<<(std::iostream& os, const Array4D<P>& array) {
os.write(reinterpret_cast<const char*>(&array.keep_nodata), sizeof(array.keep_nodata));
os.write(reinterpret_cast<const char*>(&array.nx), sizeof(array.nx));
os.write(reinterpret_cast<const char*>(&array.ny), sizeof(array.ny));
os.write(reinterpret_cast<const char*>(&array.nz), sizeof(array.nz));
os.write(reinterpret_cast<const char*>(&array.nw), sizeof(array.nw));
os.write(reinterpret_cast<const char*>(&array.vecData[0]), array.nx*array.ny*array.nz*array.nw*sizeof(P));
return os;
}
*/
template<class P> std::iostream& operator>>(std::iostream& is, Array4D<P>& array) {
is.read(reinterpret_cast<char*>(&array.keep_nodata), sizeof(array.keep_nodata));
is.read(reinterpret_cast<char*>(&array.nx), sizeof(array.nx));
is.read(reinterpret_cast<char*>(&array.ny), sizeof(array.ny));
is.read(reinterpret_cast<char*>(&array.nz), sizeof(array.nz));
is.read(reinterpret_cast<char*>(&array.nw), sizeof(array.nw));
array.vecData.resize(array.nx*array.ny*array.nz*array.nw);
is.read(reinterpret_cast<char*>(&array.vecData[0]), array.nx*array.ny*array.nz*array.nw*sizeof(P)); //30 times faster than assign() or copy()
}
template<class T> T Array4D<T>::getMin() const {
T min = std::numeric_limits<T>::max();
......
......@@ -385,36 +385,37 @@ void BufferedIOHandler::clearBuffer(){
mapBufferedGrids.clear();
}
std::ostream& operator<<(std::ostream& os, const BufferedIOHandler& data)
const std::string BufferedIOHandler::toString() const
{
std::stringstream os;
os << "<BufferedIOHandler>\n";
os << "Config& cfg = " << hex << &data.cfg << dec << "\n";
os << "IOHandler &iohandler = " << hex << &data.iohandler << dec << "\n";
os << "Config& cfg = " << hex << &cfg << dec << "\n";
os << "IOHandler &iohandler = " << hex << &iohandler << dec << "\n";
os << "Buffering " <<data.chunk_size.getJulian() << " day(s) with "
<< data.buff_before.getJulian() << " day(s) pre-buffering\n";
os << "Buffering " <<chunk_size.getJulian() << " day(s) with "
<< buff_before.getJulian() << " day(s) pre-buffering\n";
os << "Current buffer content (" << data.vec_buffer_meteo.size() << " stations, "
<< data.mapBufferedGrids.size() << " grids):\n";
os << "Current buffer content (" << vec_buffer_meteo.size() << " stations, "
<< mapBufferedGrids.size() << " grids):\n";
for(size_t ii=0; ii<data.vec_buffer_meteo.size(); ii++) {
if (!data.vec_buffer_meteo[ii].empty()){
os << std::setw(10) << data.vec_buffer_meteo[ii].front().meta.stationID << " = "
<< data.vec_buffer_meteo[ii].front().date.toString(Date::ISO) << " - "
<< data.vec_buffer_meteo[ii].back().date.toString(Date::ISO) << ", "
<< data.vec_buffer_meteo[ii].size() << " timesteps" << endl;
for(size_t ii=0; ii<vec_buffer_meteo.size(); ii++) {
if (!vec_buffer_meteo[ii].empty()){
os << std::setw(10) << vec_buffer_meteo[ii].front().meta.stationID << " = "
<< vec_buffer_meteo[ii].front().date.toString(Date::ISO) << " - "
<< vec_buffer_meteo[ii].back().date.toString(Date::ISO) << ", "
<< vec_buffer_meteo[ii].size() << " timesteps" << endl;
}
}
std::map<std::string, Grid2DObject>::const_iterator it1;
for (it1=data.mapBufferedGrids.begin(); it1 != data.mapBufferedGrids.end(); ++it1){
for (it1=mapBufferedGrids.begin(); it1 != mapBufferedGrids.end(); ++it1){
os << setw(10) << "Grid" << " = " << it1->first << ", ";
os << (it1->second).ncols << " x " << (it1->second).nrows << " @ " << (it1->second).cellsize << "m\n";
}
os << "</BufferedIOHandler>\n";
return os;
return os.str();
}
} //namespace
......@@ -126,7 +126,7 @@ class BufferedIOHandler : public IOInterface {
*/
double getAvgSamplingRate();
friend std::ostream& operator<<(std::ostream& os, const BufferedIOHandler& data);
const std::string toString() const;
friend class IOManager;
......
......@@ -80,16 +80,64 @@ bool Config::keyExists(const std::string& key, const std::string& section) const
return (it!=properties.end());
}
std::ostream& operator<<(std::ostream &os, const Config& cfg)
{
const std::string Config::toString() const {
std::stringstream os;
os << "<Config>\n";
for (map<string,string>::const_iterator it = cfg.properties.begin(); it != cfg.properties.end(); ++it){
os << "Source: " << sourcename << "\n";
for (map<string,string>::const_iterator it = properties.begin(); it != properties.end(); ++it){
os << (*it).first << " -> " << (*it).second << "\n";
}
os << "</Config>\n";
return os.str();
}
std::iostream& operator<<(std::iostream& os, const Config& cfg) {
const size_t s_source = cfg.sourcename.size();
os.write(reinterpret_cast<const char*>(&s_source), sizeof(size_t));
os.write(reinterpret_cast<const char*>(&cfg.sourcename[0]), s_source*sizeof(cfg.sourcename[0]));
const size_t s_map = cfg.properties.size();
os.write(reinterpret_cast<const char*>(&s_map), sizeof(size_t));
for (map<string,string>::const_iterator it = cfg.properties.begin(); it != cfg.properties.end(); ++it){
const string& key = (*it).first;
const size_t s_key = key.size();
os.write(reinterpret_cast<const char*>(&s_key), sizeof(size_t));
os.write(reinterpret_cast<const char*>(&key[0]), s_key*sizeof(key[0]));
const string& value = (*it).second;
const size_t s_value = value.size();
os.write(reinterpret_cast<const char*>(&s_value), sizeof(size_t));
os.write(reinterpret_cast<const char*>(&value[0]), s_value*sizeof(value[0]));
}
return os;
}
std::iostream& operator>>(std::iostream& is, Config& cfg) {
size_t s_source;
is.read(reinterpret_cast<char*>(&s_source), sizeof(size_t));
cfg.sourcename.resize(s_source);
is.read(reinterpret_cast<char*>(&cfg.sourcename[0]), s_source*sizeof(cfg.sourcename[0]));
cfg.properties.clear();
size_t s_map;
is.read(reinterpret_cast<char*>(&s_map), sizeof(size_t));
for(size_t ii=0; ii<s_map; ii++) {
size_t s_key, s_value;
is.read(reinterpret_cast<char*>(&s_key), sizeof(size_t));
string key;
key.resize(s_key);
is.read(reinterpret_cast<char*>(&key[0]), s_key*sizeof(key[0]));
is.read(reinterpret_cast<char*>(&s_value), sizeof(size_t));
string value;
value.resize(s_value);
is.read(reinterpret_cast<char*>(&value[0]), s_value*sizeof(value[0]));
cfg.properties[key] = value;
}
}
//Parsing
void Config::parseCmdLine(const std::string& cmd_line)
{
......
......@@ -131,7 +131,10 @@ class Config {
* @brief Print the content of the Config object (usefull for debugging)
* The Config is bound by "<Config>" and "</Config>" on separate lines
*/
friend std::ostream& operator<<(std::ostream& os, const Config& cfg);
const std::string toString() const;
friend std::iostream& operator<<(std::iostream& os, const Config& cfg);
friend std::iostream& operator>>(std::iostream& is, Config& cfg);
template <typename T> std::vector<T> getValue(const std::string& key, const IOUtils::ThrowOptions& opt=IOUtils::dothrow) const
{
......
......@@ -222,23 +222,69 @@ void Coords::merge(const Coords& coord2) {
* @brief Print the content of the Coords object (usefull for debugging)
* The Coords is bound by "<Coords>" and "</Coords>" on separate lines
*/
std::ostream& operator<<(std::ostream &os, const Coords& coord)
{
const std::string Coords::toString() const {
std::stringstream os;
os << "<Coords>\n";
os << "Altitude\t" << coord.altitude << "\n";
os << "Lat/Long\t" << coord.printLatLon() << "\n";
os << "Lat/Long\t" << "(" << coord.getLat() << " , " << coord.getLon() << ")" << "\n";
os << "Altitude\t" << altitude << "\n";
os << "Lat/Long\t" << printLatLon() << "\n";
os << "Lat/Long\t" << "(" << getLat() << " , " << getLon() << ")" << "\n";
std::streamsize p = os.precision();
os << "X/Y_coords\t" << std::fixed << std::setprecision(0) << "(" << coord.getEasting() << " , " << coord.getNorthing() << ")" << "\n";
os << "X/Y_coords\t" << std::fixed << std::setprecision(0) << "(" << getEasting() << " , " << getNorthing() << ")" << "\n";
os << std::resetiosflags(std::ios_base::fixed|std::ios_base::floatfield);
os.precision(p);
os << "I/J_indices\t" << "(" << coord.getGridI() << " , " << coord.getGridJ() << ")" << "\n";
os << "Projection\t" << coord.coordsystem << " " << coord.coordparam << "\n";
os << "EPSG\t\t" << coord.getEPSG() << "\n";
os << "I/J_indices\t" << "(" << getGridI() << " , " << getGridJ() << ")" << "\n";
os << "Projection\t" << coordsystem << " " << coordparam << "\n";
os << "EPSG\t\t" << getEPSG() << "\n";
os << "</Coords>\n";
return os.str();
}
std::iostream& operator<<(std::iostream& os, const Coords& coord) {
os.write(reinterpret_cast<const char*>(&coord.ref_latitude), sizeof(coord.ref_latitude));
os.write(reinterpret_cast<const char*>(&coord.ref_longitude), sizeof(coord.ref_longitude));
os.write(reinterpret_cast<const char*>(&coord.altitude), sizeof(coord.altitude));
os.write(reinterpret_cast<const char*>(&coord.latitude), sizeof(coord.latitude));
os.write(reinterpret_cast<const char*>(&coord.longitude), sizeof(coord.longitude));
os.write(reinterpret_cast<const char*>(&coord.easting), sizeof(coord.easting));
os.write(reinterpret_cast<const char*>(&coord.northing), sizeof(coord.northing));
os.write(reinterpret_cast<const char*>(&coord.grid_i), sizeof(coord.grid_i));
os.write(reinterpret_cast<const char*>(&coord.grid_j), sizeof(coord.grid_j));
os.write(reinterpret_cast<const char*>(&coord.grid_k), sizeof(coord.grid_k));
const size_t s_coordsystem = coord.coordsystem.size();
os.write(reinterpret_cast<const char*>(&s_coordsystem), sizeof(size_t));
os.write(reinterpret_cast<const char*>(&coord.coordsystem[0]), s_coordsystem*sizeof(coord.coordsystem[0]));
const size_t s_coordparam = coord.coordparam.size();
os.write(reinterpret_cast<const char*>(&s_coordparam), sizeof(size_t));
os.write(reinterpret_cast<const char*>(&coord.coordparam[0]), s_coordparam*sizeof(coord.coordparam[0]));
os.write(reinterpret_cast<const char*>(&coord.distance_algo), sizeof(coord.distance_algo));
return os;
}
std::iostream& operator>>(std::iostream& is, Coords& coord) {
is.read(reinterpret_cast<char*>(&coord.ref_latitude), sizeof(coord.ref_latitude));
is.read(reinterpret_cast<char*>(&coord.ref_longitude), sizeof(coord.ref_longitude));
is.read(reinterpret_cast<char*>(&coord.altitude), sizeof(coord.altitude));
is.read(reinterpret_cast<char*>(&coord.latitude), sizeof(coord.latitude));
is.read(reinterpret_cast<char*>(&coord.longitude), sizeof(coord.longitude));
is.read(reinterpret_cast<char*>(&coord.easting), sizeof(coord.easting));
is.read(reinterpret_cast<char*>(&coord.northing), sizeof(coord.northing));
is.read(reinterpret_cast<char*>(&coord.grid_i), sizeof(coord.grid_i));
is.read(reinterpret_cast<char*>(&coord.grid_j), sizeof(coord.grid_j));
is.read(reinterpret_cast<char*>(&coord.grid_k), sizeof(coord.grid_k));
size_t s_coordsystem, s_coordparam;
is.read(reinterpret_cast<char*>(&s_coordsystem), sizeof(size_t));
coord.coordsystem.resize(s_coordsystem);
is.read(reinterpret_cast<char*>(&coord.coordsystem[0]), s_coordsystem*sizeof(coord.coordsystem[0]));
is.read(reinterpret_cast<char*>(&s_coordparam), sizeof(size_t));
coord.coordparam.resize(s_coordparam);
is.read(reinterpret_cast<char*>(&coord.coordparam[0]), s_coordparam*sizeof(coord.coordparam[0]));
is.read(reinterpret_cast<char*>(&coord.distance_algo), sizeof(coord.distance_algo));
}
/**
* @brief Default constructor
* This constructor builds a dummy object that performs no conversions but can be used for comparison
......
......@@ -85,7 +85,9 @@ class Coords {
std::string printLatLon() const;
short int getEPSG() const;
friend std::ostream& operator<<(std::ostream& os, const Coords& coord);
const std::string toString() const;
friend std::iostream& operator<<(std::iostream& os, const Coords& coord);
friend std::iostream& operator>>(std::iostream& is, Coords& coord);
//Setter methods
void setLatLon(const double in_latitude, const double in_longitude, const double in_altitude, const bool in_update=true);
......
......@@ -994,6 +994,46 @@ double DEMObject::safeGet(const int i, const int j)
return grid2D((unsigned)i, (unsigned)j);
}