source: ntrip/trunk/BNC/bnctabledlg.cpp@ 1364

Last change on this file since 1364 was 1364, checked in by mervart, 15 years ago

* empty log message *

File size: 15.8 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
27 * -------------------------------------------------------------------------
28 *
29 * Class: bncTableDlg
30 *
31 * Purpose: Displays the source table, allows mountpoints selection
32 *
33 * Author: L. Mervart
34 *
35 * Created: 24-Dec-2005
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <iostream>
42
43#include "bnctabledlg.h"
44#include "bncgetthread.h"
45#include "bncsocket.h"
46
47using namespace std;
48
49// Constructor
50////////////////////////////////////////////////////////////////////////////
51bncTableDlg::bncTableDlg(QWidget* parent) : QDialog(parent) {
52
53 setMinimumSize(600,400);
54 setWindowTitle(tr("Add Mountpoints"));
55
56 QVBoxLayout* mainLayout = new QVBoxLayout(this);
57
58 QSettings settings;
59 _casterHostLineEdit = new QComboBox();
60 _casterHostLineEdit->setDuplicatesEnabled(false);
61 _casterHostLineEdit->setEditable(true);
62 int ww = QFontMetrics(_casterHostLineEdit->font()).width('w');
63 _casterHostLineEdit->setMaximumWidth(20*ww);
64 QStringList casterHostList = settings.value("casterHostList").toStringList();
65 _casterHostLineEdit->addItem(settings.value("casterHost").toString());
66 for (int ii = 0; ii < casterHostList.count(); ii++) {
67 QString item = casterHostList[ii];
68 if (_casterHostLineEdit->findText(item, Qt::MatchFixedString) < 0) {
69 _casterHostLineEdit->addItem(item);
70 }
71 }
72 _casterPortLineEdit = new QLineEdit(settings.value("casterPort").toString());
73 _casterPortLineEdit->setMaximumWidth(9*ww);
74 _casterUserLineEdit = new QLineEdit(settings.value("casterUser").toString());
75 _casterUserLineEdit->setMaximumWidth(9*ww);
76 _casterPasswordLineEdit = new QLineEdit(settings.value("casterPassword").toString());
77 _casterPasswordLineEdit->setMaximumWidth(9*ww);
78 _casterPasswordLineEdit->setEchoMode(QLineEdit::Password);
79
80 _ntripVersionComboBox = new QComboBox();
81 _ntripVersionComboBox->addItems(QString("1,2,AUTO").split(","));
82 int kk = _ntripVersionComboBox->findText(settings.value("ntripVersion").toString());
83 if (kk != -1) {
84 _ntripVersionComboBox->setCurrentIndex(kk);
85 }
86
87 // WhatsThis
88 // ---------
89 _casterUserLineEdit->setWhatsThis(tr("Access to some streams on NTRIP broadcasters may be restricted. You'll need to enter a valid 'User ID' and 'Password' for access to these protected streams. Accounts are usually provided per NTRIP broadcaster through a registration process. Register through <u>http://igs.bkg.bund.de/index_ntrip_reg.htm</u> for access to protected streams on <u>www.euref-ip.net</u> and <u>www.igs-ip.net</u>."));
90 _casterPortLineEdit->setWhatsThis(tr("Enter the NTRIP broadcaster hostname or IP number and port number. <u>http://www.rtcm-ntrip.org/home</u> provides information about known NTRIP broadcaster installations. Note that EUREF and IGS operate NTRIP broadcasters at <u>http://www.euref-ip.net/home</u> and <u>http://www.igs-ip.net/home</u>."));
91 _casterHostLineEdit->setWhatsThis(tr("Enter the NTRIP broadcaster hostname or IP number and port number. <u>http://www.rtcm-ntrip.org/home</u> provides information about known NTRIP broadcaster installations. Note that EUREF and IGS operate NTRIP broadcasters at <u>http://www.euref-ip.net/home</u> and <u>http://www.igs-ip.net/home</u>."));
92 _casterPasswordLineEdit->setWhatsThis(tr("Access to some streams on NTRIP broadcasters may be restricted. You'll need to enter a valid 'User ID' and 'Password' for access to these protected streams. Accounts are usually provided per NTRIP broadcaster through a registration procedure. Register through <u>http://igs.bkg.bund.de/index_ntrip_reg.htm</u> for access to protected streams on <u>www.euref-ip.net</u> and <u>www.igs-ip.net</u>."));
93
94 QGridLayout* editLayout = new QGridLayout;
95 editLayout->addWidget(new QLabel(tr("Caster host")), 0, 0);
96 editLayout->addWidget(_casterHostLineEdit, 0, 1);
97 editLayout->addWidget(new QLabel(tr("Caster port")), 0, 2);
98 editLayout->addWidget(_casterPortLineEdit, 0, 3);
99 editLayout->addWidget(new QLabel(tr("NTRIP Version")), 0, 4);
100 editLayout->addWidget(_ntripVersionComboBox, 0, 5);
101 editLayout->addWidget(new QLabel(tr("User")), 1, 0);
102 editLayout->addWidget(_casterUserLineEdit, 1, 1);
103 editLayout->addWidget(new QLabel(tr("Password")), 1, 2);
104 editLayout->addWidget(_casterPasswordLineEdit, 1, 3);
105
106 mainLayout->addLayout(editLayout);
107
108 _table = new QTableWidget(this);
109 _table->setWhatsThis(tr("<p>Use the 'Get Table' button to download the sourcetable from the NTRIP broadcaster. Select the desired streams line by line, using +Shift and +Ctrl when necessary. Hit 'OK' to return to the main window.</p><p>Pay attention to data fields 'format' and 'format-details'. Keep in mind that BNC can only decode and convert streams that come in RTCM Version 2.x, RTCM Version 3.x, or RTIGS format. RTCM Version 2.x streams must contain message Type 18 and 19 or 20 and 21 while RTCM Version 3.x streams must contain GPS or SBAS message Type 1002 or 1004 and may contain GLONASS message types 1010 or 1012. See data field 'format-details' for available message types and their repetition rates in brackets.</p><p>Note that in order to produce RINEX Navigation files, RTCM Version 3.x streams containing message Type 1019 (GPS) and 1020 (GLONASS) or RTIGS streams are required.</p><p>Search for RTCM Version 3.x streams containing (premature) message Types 4056 and 4057 if you need corrections to Broadcast Ephemeris.</p><p>The content of data field 'nmea' tells you whether a stream retrieval needs to be initiated by BNC by sending an NMEA-GGA message containing the user (or virtual reference station)'s coordinate.</p>"));
110 connect(_table, SIGNAL(itemSelectionChanged()),
111 this, SLOT(slotSelectionChanged()));
112 mainLayout->addWidget(_table);
113
114 _buttonWhatsThis = new QPushButton(tr("Help=Shift+F1"), this);
115 connect(_buttonWhatsThis, SIGNAL(clicked()), this, SLOT(slotWhatsThis()));
116
117 _buttonGet = new QPushButton(tr("Get table"), this);
118 _buttonGet->setDefault(true);
119 connect(_buttonGet, SIGNAL(clicked()), this, SLOT(slotGetTable()));
120
121 _buttonCancel = new QPushButton(tr("Cancel"), this);
122 connect(_buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
123
124 _buttonOK = new QPushButton(tr("OK"), this);
125 connect(_buttonOK, SIGNAL(clicked()), this, SLOT(accept()));
126
127 QHBoxLayout* buttonLayout = new QHBoxLayout;
128 buttonLayout->addWidget(_buttonWhatsThis);
129 buttonLayout->addStretch(1);
130 buttonLayout->addWidget(_buttonGet);
131 buttonLayout->addWidget(_buttonCancel);
132 buttonLayout->addWidget(_buttonOK);
133
134 mainLayout->addLayout(buttonLayout);
135}
136
137// Destructor
138////////////////////////////////////////////////////////////////////////////
139bncTableDlg::~bncTableDlg() {
140 if (_table) {
141 for (int ir = 0; ir < _table->rowCount(); ir++) {
142 for (int ic = 0; ic < _table->columnCount(); ic++) {
143 delete _table->item(ir,ic);
144 }
145 }
146 }
147}
148
149// Read Table the caster (static)
150////////////////////////////////////////////////////////////////////////////
151t_irc bncTableDlg::getFullTable(const QString& casterHost,
152 int casterPort, const QByteArray& ntripVersion,
153 QStringList& allLines, bool alwaysRead) {
154
155 static QMutex mutex;
156 static QMap<QString, QStringList> allTables;
157
158 QMutexLocker locker(&mutex);
159
160 if (!alwaysRead && allTables.find(casterHost) != allTables.end()) {
161 allLines = allTables.find(casterHost).value();
162 return success;
163 }
164
165 allLines.clear();
166
167 QUrl url;
168 url.setHost(casterHost);
169 url.setPort(casterPort);
170
171 // Send the Request
172 // ----------------
173 const int timeOut = 10*1000;
174 QString msg;
175 bncSocket* socket = new bncSocket();
176 if (socket->request(url, "", "", "", ntripVersion, timeOut, msg) != success) {
177 delete socket;
178 return failure;
179 }
180
181 // Read Caster Response
182 // --------------------
183 bool proxyRespond = false;
184 bool first = true;
185 while (true) {
186 if (socket->canReadLine()) {
187 QString line = socket->readLine();
188
189 // Skip messages from proxy server
190 // -------------------------------
191 if (line.indexOf("SOURCETABLE 200 OK") == -1 &&
192 line.indexOf("200 OK") != -1 ) {
193 proxyRespond = true;
194 }
195 if (proxyRespond) {
196 if (line.trimmed().isEmpty()) {
197 proxyRespond = false;
198 }
199 continue;
200 }
201
202 allLines.push_back(line);
203 if (first) {
204 first = false;
205 if (line.indexOf("SOURCETABLE 200 OK") != 0) {
206 if (ntripVersion == "1") {
207 break;
208 }
209 }
210 }
211 else {
212 if (line.indexOf("ENDSOURCETABLE") == 0) {
213 break;
214 }
215 }
216 }
217 else {
218 cout << "before waitForReadyRead" << endl;
219 socket->waitForReadyRead(timeOut);
220 cout << "after waitForReadyRead" << " "
221 << socket->bytesAvailable() << endl;
222 if (socket->bytesAvailable() > 0) {
223 continue;
224 }
225 else {
226 break;
227 }
228 }
229 }
230 /// delete socket;
231
232 allTables.insert(casterHost, allLines);
233 return success;
234}
235
236// Read Table from Caster
237////////////////////////////////////////////////////////////////////////////
238void bncTableDlg::slotGetTable() {
239
240 _buttonGet->setEnabled(false);
241
242 _allLines.clear();
243
244 if ( getFullTable(_casterHostLineEdit->currentText(),
245 _casterPortLineEdit->text().toInt(),
246 _ntripVersionComboBox->currentText().toAscii(),
247 _allLines) != success ) {
248 QMessageBox::warning(0, "BNC", "Cannot retrieve table of data");
249 _buttonGet->setEnabled(true);
250 return;
251 }
252
253 QStringList lines;
254 QStringListIterator it(_allLines);
255 while (it.hasNext()) {
256 QString line = it.next();
257 if (line.indexOf("STR") == 0) {
258 lines.push_back(line);
259 }
260 }
261
262 static const QStringList labels = QString("mountpoint,identifier,format,"
263 "format-details,carrier,system,network,country,latitude,longitude,"
264 "nmea,solution,generator,compress.,authentic.,fee,bitrate,"
265 "misc").split(",");
266
267 if (lines.size() > 0) {
268 _table->setSelectionMode(QAbstractItemView::ExtendedSelection);
269 _table->setSelectionBehavior(QAbstractItemView::SelectRows);
270
271 QStringList hlp = lines[0].split(";");
272 _table->setColumnCount(hlp.size()-1);
273 _table->setRowCount(lines.size());
274
275 QListIterator<QString> it(lines);
276 int nRow = -1;
277 while (it.hasNext()) {
278 QStringList columns = it.next().split(";");
279 ++nRow;
280 for (int ic = 0; ic < columns.size()-1; ic++) {
281
282 if (ic+1 == 11) { if (columns[ic+1] == "0") { columns[ic+1] = "no"; } else { columns[ic+1] = "yes"; }}
283
284 QTableWidgetItem* it = new QTableWidgetItem(columns[ic+1]);
285 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
286 _table->setItem(nRow, ic, it);
287 }
288 }
289 _table->sortItems(0);
290 _table->setHorizontalHeaderLabels(labels);
291 _table->setSortingEnabled(true);
292
293 int ww = QFontMetrics(this->font()).width('w');
294 _table->horizontalHeader()->resizeSection(0,10*ww);
295 _table->horizontalHeader()->resizeSection(2,8*ww);
296 _table->horizontalHeader()->resizeSection(3,15*ww);
297 _table->horizontalHeader()->resizeSection(4,8*ww);
298 _table->horizontalHeader()->resizeSection(5,8*ww);
299 _table->horizontalHeader()->resizeSection(6,8*ww);
300 _table->horizontalHeader()->resizeSection(7,8*ww);
301 _table->horizontalHeader()->resizeSection(8,8*ww);
302 _table->horizontalHeader()->resizeSection(9,8*ww);
303 _table->horizontalHeader()->resizeSection(10,8*ww);
304 _table->horizontalHeader()->resizeSection(11,8*ww);
305 _table->horizontalHeader()->resizeSection(12,15*ww);
306 _table->horizontalHeader()->resizeSection(13,8*ww);
307 _table->horizontalHeader()->resizeSection(14,8*ww);
308 _table->horizontalHeader()->resizeSection(15,8*ww);
309 _table->horizontalHeader()->resizeSection(16,8*ww);
310 _table->horizontalHeader()->resizeSection(17,15*ww);
311 }
312}
313
314// Accept slot
315////////////////////////////////////////////////////////////////////////////
316void bncTableDlg::accept() {
317
318 QSettings settings;
319 settings.setValue("casterHost", _casterHostLineEdit->currentText());
320 QStringList casterHostList;
321 for (int ii = 0; ii < _casterHostLineEdit->count(); ii++) {
322 casterHostList.push_back(_casterHostLineEdit->itemText(ii));
323 }
324 settings.setValue("casterHostList", casterHostList);
325 settings.setValue("casterPort", _casterPortLineEdit->text());
326 settings.setValue("ntripVersion", _ntripVersionComboBox->currentText());
327 settings.setValue("casterUser", _casterUserLineEdit->text());
328 settings.setValue("casterPassword", _casterPasswordLineEdit->text());
329
330 QStringList* mountPoints = new QStringList;
331
332 if (_table) {
333 for (int ir = 0; ir < _table->rowCount(); ir++) {
334 QTableWidgetItem* item = _table->item(ir,0);
335 QString format = _table->item(ir,2)->text();
336 QString latitude = _table->item(ir,8)->text();
337 QString longitude = _table->item(ir,9)->text();
338 QString nmea = _table->item(ir,10)->text();
339 QString ntripVersion = _ntripVersionComboBox->currentText();
340 format.replace(" ", "_");
341 if (_table->isItemSelected(item)) {
342 QUrl url;
343 url.setUserName(QUrl::toPercentEncoding(_casterUserLineEdit->text()));
344 url.setPassword(QUrl::toPercentEncoding(_casterPasswordLineEdit->text()));
345 url.setHost(_casterHostLineEdit->currentText());
346 url.setPort(_casterPortLineEdit->text().toInt());
347 url.setPath(item->text());
348
349 mountPoints->push_back(url.toString() + " " + format + " " + latitude
350 + " " + longitude + " " + nmea + " " + ntripVersion);
351 }
352 }
353 }
354 emit newMountPoints(mountPoints);
355
356 QDialog::accept();
357}
358
359// User changed the selection of mountPoints
360////////////////////////////////////////////////////////////////////////////
361void bncTableDlg::slotSelectionChanged() {
362 if (_table->selectedItems().isEmpty()) {
363 }
364}
365
366// Create RINEX skeleton header
367////////////////////////////////////////////////////////////////////////////
368void bncTableDlg::slotSkl() {
369
370 int nRows = _table->rowCount();
371 for (int iRow = 0; iRow < nRows; iRow++) {
372 if (_table->isItemSelected(_table->item(iRow,1))) {
373 QString staID = _table->item(iRow,0)->text();
374 QString net = _table->item(iRow,6)->text();
375
376 QString ftpDir;
377 QStringListIterator it(_allLines);
378 while (it.hasNext()) {
379 QString line = it.next();
380 if (line.indexOf("NET") == 0) {
381 QStringList tags = line.split(';');
382 if (tags.at(1) == net) {
383 ftpDir = tags.at(6);
384 break;
385 }
386 }
387 }
388
389 if (!ftpDir.isEmpty()) {
390 QUrl url(ftpDir);
391 QMessageBox::warning(0, "Warning", url.host() + "\n" + url.path() +
392 "\nnot yet implemented");
393 }
394 }
395 }
396}
397
398// Whats This Help
399void bncTableDlg::slotWhatsThis() {
400QWhatsThis::enterWhatsThisMode();
401}
402
403
Note: See TracBrowser for help on using the repository browser.