Index: trunk/BNC/rinex/bncpostprocess.cpp
===================================================================
--- trunk/BNC/rinex/bncpostprocess.cpp	(revision 3721)
+++ trunk/BNC/rinex/bncpostprocess.cpp	(revision 3721)
@@ -0,0 +1,185 @@
+// Part of BNC, a utility for retrieving decoding and
+// converting GNSS data streams from NTRIP broadcasters.
+//
+// Copyright (C) 2007
+// German Federal Agency for Cartography and Geodesy (BKG)
+// http://www.bkg.bund.de
+// Czech Technical University Prague, Department of Geodesy
+// http://www.fsv.cvut.cz
+//
+// Email: euref-ip@bkg.bund.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation, version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/* -------------------------------------------------------------------------
+ * BKG NTRIP Client
+ * -------------------------------------------------------------------------
+ *
+ * Class:      t_postProcessing
+ *
+ * Purpose:    Precise Point Positioning in Post-Processing Mode
+ *
+ * Author:     L. Mervart
+ *
+ * Created:    22-Jan-2012
+ *
+ * Changes:    
+ *
+ * -----------------------------------------------------------------------*/
+
+#include <iostream>
+#include "bncpostprocess.h"
+#include "bncapp.h"
+#include "bncsettings.h"
+#include "pppopt.h"
+#include "bncpppclient.h"
+#include "rinex/rnxobsfile.h"
+#include "rnxnavfile.h"
+#include "corrfile.h"
+#include "bncsettings.h"
+#include "bncutils.h"
+
+using namespace std;
+
+// Constructor
+////////////////////////////////////////////////////////////////////////////
+t_postProcessing::t_postProcessing(QObject* parent) : QThread(parent) {
+  _opt        = new t_pppOpt();
+  _rnxObsFile = 0;
+  _rnxNavFile = 0;
+  _corrFile   = 0;
+  _pppClient  = 0;
+
+  bncSettings settings;
+
+  QString outFileName = settings.value("postOutFile").toString();
+  if (outFileName.isEmpty()) {
+    _outFile   = 0;
+    _outStream = 0;
+  }
+  else {
+    expandEnvVar(outFileName);
+    _outFile = new QFile(outFileName);
+    _outFile->open(QIODevice::WriteOnly | QIODevice::Text);
+    _outStream = new QTextStream();
+    _outStream->setDevice(_outFile);
+  }
+}
+
+// Destructor
+////////////////////////////////////////////////////////////////////////////
+t_postProcessing::~t_postProcessing() {
+  delete _pppClient;
+  delete _rnxNavFile;
+  delete _rnxObsFile;
+  delete _corrFile;
+  delete _opt;
+  delete _outStream;
+  delete _outFile;
+}
+
+// Write a Program Message
+////////////////////////////////////////////////////////////////////////////
+void t_postProcessing::slotMessage(QByteArray msg, bool /* showOnScreen */) {
+  if (_outStream) {
+    *_outStream << endl << msg;
+    _outStream->flush();
+  }
+  else {
+    ((bncApp*) qApp)->slotMessage(msg, false);
+  }
+}
+
+//  
+////////////////////////////////////////////////////////////////////////////
+void t_postProcessing::run() {
+
+  if (_pppClient) {
+    return;
+  }
+  else {
+    _rnxObsFile = new t_rnxObsFile(_opt->obsFileName);
+    _rnxNavFile = new t_rnxNavFile(_opt->navFileName);
+    _pppClient  = new bncPPPclient("POST", _opt, false);
+
+    if (!_opt->corrFileName.isEmpty()) {
+      _corrFile = new t_corrFile(_opt->corrFileName);
+      connect(_corrFile, SIGNAL(newCorrections(QList<QString>)),
+              _pppClient, SLOT(slotNewCorrections(QList<QString>)));
+    }
+
+    connect(_pppClient, SIGNAL(newMessage(QByteArray,bool)), 
+            this, SLOT(slotMessage(const QByteArray,bool)));
+  }
+
+  // Read Ephemerides
+  // ----------------
+  t_eph* eph = 0;
+  while ( (eph = _rnxNavFile->getNextEph()) != 0 ) {
+    if (_pppClient->putNewEph(eph) != success) {
+      delete eph; eph = 0;
+    }
+  }
+
+  // Read/Process Observations
+  // -------------------------
+  int   nEpo = 0;
+  const t_rnxObsFile::t_rnxEpo* epo = 0;
+  while ( (epo = _rnxObsFile->nextEpoch()) != 0 ) {
+    ++nEpo;
+
+    if (_corrFile) {
+      _corrFile->syncRead(epo->tt);
+    }
+
+    for (unsigned iObs = 0; iObs < epo->rnxSat.size(); iObs++) {
+      const t_rnxObsFile::t_rnxSat& rnxSat = epo->rnxSat[iObs];
+      t_obs obs;
+      strncpy(obs.StatID, _rnxObsFile->markerName().toAscii().constData(),
+              sizeof(obs.StatID));
+      obs.satSys   = rnxSat.satSys;
+      obs.satNum   = rnxSat.satNum;
+      obs.GPSWeek  = epo->tt.gpsw();
+      obs.GPSWeeks = epo->tt.gpssec();
+      for (int iType = 0; iType < _rnxObsFile->nTypes(obs.satSys); iType++) {
+        QByteArray type = _rnxObsFile->obsType(obs.satSys,iType).toAscii();
+        if      (type.indexOf("C1") == 0 && obs.C1  == 0.0) {
+          obs.C1 = rnxSat.obs[iType];
+        }
+        else if (type.indexOf("P1") == 0 && obs.P1  == 0.0) {
+          obs.P1 = rnxSat.obs[iType];
+        }
+        else if (type.indexOf("L1") == 0 && obs.L1C == 0.0) {
+          obs.L1C = rnxSat.obs[iType];
+        }
+        else if (type.indexOf("C2") == 0 && obs.C2  == 0.0) {
+          obs.C2 = rnxSat.obs[iType];
+        }
+        else if (type.indexOf("P2") == 0 && obs.P2  == 0.0) {
+          obs.P2 = rnxSat.obs[iType];
+        }
+        else if (type.indexOf("L2") == 0 && obs.L2C == 0.0) {
+          obs.L2C = rnxSat.obs[iType];
+        }
+      }
+      _pppClient->putNewObs(obs);
+    }
+    if (nEpo % 10 == 0) {
+      emit progress(nEpo);
+    }
+  }
+
+  emit finished();
+  deleteLater();
+}
Index: trunk/BNC/rinex/bncpostprocess.h
===================================================================
--- trunk/BNC/rinex/bncpostprocess.h	(revision 3721)
+++ trunk/BNC/rinex/bncpostprocess.h	(revision 3721)
@@ -0,0 +1,69 @@
+// Part of BNC, a utility for retrieving decoding and
+// converting GNSS data streams from NTRIP broadcasters.
+//
+// Copyright (C) 2007
+// German Federal Agency for Cartography and Geodesy (BKG)
+// http://www.bkg.bund.de
+// Czech Technical University Prague, Department of Geodesy
+// http://www.fsv.cvut.cz
+//
+// Email: euref-ip@bkg.bund.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation, version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef BNCPOSTPROCESS_H
+#define BNCPOSTPROCESS_H
+
+#include <QtCore>
+#include "bncconst.h"
+extern "C" {
+#include "rtcm3torinex.h"
+}
+
+class t_pppOpt;
+class bncPPPclient;
+class t_rnxObsFile;
+class t_rnxNavFile;
+class t_corrFile;
+
+class t_postProcessing : public QThread {
+Q_OBJECT
+ 
+ public:
+  t_postProcessing(QObject* parent);
+
+ protected:
+  ~t_postProcessing();
+
+ signals:
+  void progress(int);
+  void finished();
+   
+ public slots:
+  void slotMessage(QByteArray msg, bool showOnScreen);
+
+ public:
+  virtual void run();
+ 
+ private:
+  t_pppOpt*     _opt;
+  bncPPPclient* _pppClient;
+  t_rnxObsFile* _rnxObsFile;
+  t_rnxNavFile* _rnxNavFile;
+  t_corrFile*   _corrFile;
+  QFile*        _outFile;
+  QTextStream*  _outStream;
+};
+
+#endif
Index: trunk/BNC/rinex/corrfile.cpp
===================================================================
--- trunk/BNC/rinex/corrfile.cpp	(revision 3721)
+++ trunk/BNC/rinex/corrfile.cpp	(revision 3721)
@@ -0,0 +1,118 @@
+// Part of BNC, a utility for retrieving decoding and
+// converting GNSS data streams from NTRIP broadcasters.
+//
+// Copyright (C) 2007
+// German Federal Agency for Cartography and Geodesy (BKG)
+// http://www.bkg.bund.de
+// Czech Technical University Prague, Department of Geodesy
+// http://www.fsv.cvut.cz
+//
+// Email: euref-ip@bkg.bund.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation, version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/* -------------------------------------------------------------------------
+ * BKG NTRIP Client
+ * -------------------------------------------------------------------------
+ *
+ * Class:      t_corrFile
+ *
+ * Purpose:    Reads DGPS Correction File
+ *
+ * Author:     L. Mervart
+ *
+ * Created:    12-Feb-2012
+ *
+ * Changes:    
+ *
+ * -----------------------------------------------------------------------*/
+
+#include <iostream>
+#include "corrfile.h"
+#include "bncutils.h"
+
+using namespace std;
+
+// Constructor
+////////////////////////////////////////////////////////////////////////////
+t_corrFile::t_corrFile(QString fileName) {
+  expandEnvVar(fileName);
+  _file   = new QFile(fileName);
+  _file->open(QIODevice::ReadOnly | QIODevice::Text);
+  _stream = new QTextStream();
+  _stream->setDevice(_file);
+}
+
+// Destructor
+////////////////////////////////////////////////////////////////////////////
+t_corrFile::~t_corrFile() {
+  delete _stream;
+  delete _file;
+}
+
+// Read till a given time
+////////////////////////////////////////////////////////////////////////////
+void t_corrFile::syncRead(const bncTime& tt) {
+
+  if (stopRead(tt)) {
+    return;
+  }
+
+  QList<QString> corrs;
+
+  if (!_lastLine.isEmpty()) {
+    corrs << _lastLine;
+  }
+
+  while (_stream->status() == QTextStream::Ok && !_stream->atEnd()) {
+    QString line = _stream->readLine();
+    if (line.isEmpty() || line[0] == '!') {
+      continue;
+    }
+    _lastLine = line;
+
+    if (stopRead(tt)) {
+      if (corrs.size()) {
+        emit newCorrections(corrs);
+      }
+      return;
+    }
+    else {
+      corrs << _lastLine;
+    }
+  }
+}
+
+// Read till a given time
+////////////////////////////////////////////////////////////////////////////
+bool t_corrFile::stopRead(const bncTime& tt) {
+
+  if (_lastLine.isEmpty()) {
+    return false;
+  }
+
+  QTextStream in(_lastLine.toAscii(), QIODevice::ReadOnly);
+  int    messageType, updateInterval, GPSweek;
+  double GPSweeks;
+  in >> messageType >> updateInterval >> GPSweek >> GPSweeks;
+
+  bncTime tNew(GPSweek, GPSweeks);
+
+  if (tNew >= tt) {
+    return true;
+  }    
+  else {
+    return false;
+  }
+}
Index: trunk/BNC/rinex/corrfile.h
===================================================================
--- trunk/BNC/rinex/corrfile.h	(revision 3721)
+++ trunk/BNC/rinex/corrfile.h	(revision 3721)
@@ -0,0 +1,50 @@
+// Part of BNC, a utility for retrieving decoding and
+// converting GNSS data streams from NTRIP broadcasters.
+//
+// Copyright (C) 2007
+// German Federal Agency for Cartography and Geodesy (BKG)
+// http://www.bkg.bund.de
+// Czech Technical University Prague, Department of Geodesy
+// http://www.fsv.cvut.cz
+//
+// Email: euref-ip@bkg.bund.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation, version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef CORRFILE_H
+#define CORRFILE_H
+
+#include <QtCore>
+#include "bncconst.h"
+#include "bnctime.h"
+
+class t_corrFile : public QObject {
+ Q_OBJECT
+
+ public:
+  t_corrFile(QString fileName);
+  ~t_corrFile();
+  void syncRead(const bncTime& tt);
+
+ signals:
+  void newCorrections(QList<QString>);
+
+ private:
+  bool stopRead(const bncTime& tt);
+  QFile*       _file;
+  QTextStream* _stream;
+  QString      _lastLine;
+};
+
+#endif
Index: trunk/BNC/rinex/rnxnavfile.cpp
===================================================================
--- trunk/BNC/rinex/rnxnavfile.cpp	(revision 3721)
+++ trunk/BNC/rinex/rnxnavfile.cpp	(revision 3721)
@@ -0,0 +1,158 @@
+// Part of BNC, a utility for retrieving decoding and
+// converting GNSS data streams from NTRIP broadcasters.
+//
+// Copyright (C) 2007
+// German Federal Agency for Cartography and Geodesy (BKG)
+// http://www.bkg.bund.de
+// Czech Technical University Prague, Department of Geodesy
+// http://www.fsv.cvut.cz
+//
+// Email: euref-ip@bkg.bund.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation, version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/* -------------------------------------------------------------------------
+ * BKG NTRIP Client
+ * -------------------------------------------------------------------------
+ *
+ * Class:      t_rnxNavFile
+ *
+ * Purpose:    Reads RINEX Navigation File
+ *
+ * Author:     L. Mervart
+ *
+ * Created:    24-Jan-2012
+ *
+ * Changes:    
+ *
+ * -----------------------------------------------------------------------*/
+
+#include <iostream>
+#include <newmatio.h>
+#include "rnxnavfile.h"
+#include "bncutils.h"
+#include "RTCM3/ephemeris.h"
+
+using namespace std;
+
+// Constructor
+////////////////////////////////////////////////////////////////////////////
+t_rnxNavFile::t_rnxNavHeader::t_rnxNavHeader() {
+  _version = 0.0;
+  _glonass = false;
+}
+
+// Destructor
+////////////////////////////////////////////////////////////////////////////
+t_rnxNavFile::t_rnxNavHeader::~t_rnxNavHeader() {
+}
+
+// Read Header
+////////////////////////////////////////////////////////////////////////////
+t_irc t_rnxNavFile::t_rnxNavHeader::read(QTextStream* stream) {
+  while (stream->status() == QTextStream::Ok && !stream->atEnd()) {
+    QString line = stream->readLine();
+    if (line.isEmpty()) {
+      continue;
+    }
+    QString value = line.left(60).trimmed();
+    QString key   = line.mid(60).trimmed();
+    if      (key == "END OF HEADER") {
+      break;
+    }
+    else if (key == "RINEX VERSION / TYPE") {
+      QTextStream in(value.toAscii(), QIODevice::ReadOnly);
+      in >> _version;
+      if (value.indexOf("GLONASS") != -1) {
+        _glonass = true;
+      }
+    }
+  }
+
+  return success;
+}
+
+// Constructor
+////////////////////////////////////////////////////////////////////////////
+t_rnxNavFile::t_rnxNavFile(QString fileName) {
+  expandEnvVar(fileName);
+  _file   = new QFile(fileName);
+  _file->open(QIODevice::ReadOnly | QIODevice::Text);
+  _stream = new QTextStream();
+  _stream->setDevice(_file);
+  _header.read(_stream);
+}
+
+// Destructor
+////////////////////////////////////////////////////////////////////////////
+t_rnxNavFile::~t_rnxNavFile() {
+  delete _stream;
+  delete _file;
+}
+
+// Read Next Ephemeris
+////////////////////////////////////////////////////////////////////////////
+t_eph* t_rnxNavFile::getNextEph() {
+
+  t_eph* eph = 0;
+
+  while (_stream->status() == QTextStream::Ok && !_stream->atEnd()) {
+    QString line = _stream->readLine();
+    if (line.isEmpty()) {
+      continue;
+    }
+    QStringList hlp = line.split(QRegExp("\\s+"), QString::SkipEmptyParts);
+    QString prn;
+    if (version() >= 3.0) {
+      prn = hlp.at(0);
+    }
+    else {
+      if (glonass()) {
+        prn = QString("R%1").arg(hlp.at(0).toInt(), 2, 10, QChar('0'));
+      }
+      else {
+        prn = QString("G%1").arg(hlp.at(0).toInt(), 2, 10, QChar('0'));
+      }
+    }
+    QStringList lines; lines << line;
+    if      (prn[0] == 'G') {
+      for (int ii = 1; ii < 8; ii++) {
+        lines << _stream->readLine();
+      }
+      eph = new t_ephGPS(version(), lines);
+    }
+    else if (prn[0] == 'R') {
+      for (int ii = 1; ii < 4; ii++) {
+        lines << _stream->readLine();
+      }
+      eph = new t_ephGlo(version(), lines);
+    }
+    else if (prn[0] == 'E') {
+      for (int ii = 1; ii < 8; ii++) {
+        lines << _stream->readLine();
+      }
+      eph = new t_ephGal(version(), lines);
+    }
+    if (eph && eph->ok()) {
+      // ColumnVector xc(4);
+      // ColumnVector vv(3);
+      // eph->position(eph->GPSweek(), eph->GPSweeks(), xc.data(), vv.data());
+      // cout << eph->prn().toAscii().data() << " " << xc.t();
+      return eph;
+    }
+  }
+
+  delete eph;
+  return 0;
+}
Index: trunk/BNC/rinex/rnxnavfile.h
===================================================================
--- trunk/BNC/rinex/rnxnavfile.h	(revision 3721)
+++ trunk/BNC/rinex/rnxnavfile.h	(revision 3721)
@@ -0,0 +1,62 @@
+// Part of BNC, a utility for retrieving decoding and
+// converting GNSS data streams from NTRIP broadcasters.
+//
+// Copyright (C) 2007
+// German Federal Agency for Cartography and Geodesy (BKG)
+// http://www.bkg.bund.de
+// Czech Technical University Prague, Department of Geodesy
+// http://www.fsv.cvut.cz
+//
+// Email: euref-ip@bkg.bund.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation, version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef RNXNAVFILE_H
+#define RNXNAVFILE_H
+
+#include <QtCore>
+#include "bncconst.h"
+
+class t_pppOpt;
+class bncPPPclient;
+class t_eph;
+
+class t_rnxNavFile {
+
+  class t_rnxNavHeader {
+   public:
+    t_rnxNavHeader();
+    ~t_rnxNavHeader();
+    t_irc read(QTextStream* stream);
+    float version() const {return _version;}
+    bool  glonass() const {return _glonass;}
+   private:
+    float   _version;
+    bool    _glonass;
+  };
+ 
+ public:
+  t_rnxNavFile(QString fileName);
+  ~t_rnxNavFile();
+  t_eph* getNextEph();
+  float version() const {return _header.version();}
+  bool  glonass() const {return _header.glonass();}
+
+ private:
+  t_rnxNavHeader _header;
+  QFile*         _file;
+  QTextStream*   _stream;
+};
+
+#endif
