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

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

* empty log message *

File size: 15.7 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 break;
207 }
208 }
209 else {
210 if (line.indexOf("ENDSOURCETABLE") == 0) {
211 break;
212 }
213 }
214 }
215 else {
216 cout << "before waitForReadyRead" << endl;
217 socket->waitForReadyRead(timeOut);
218 cout << "after waitForReadyRead" << " "
219 << socket->bytesAvailable() << endl;
220 if (socket->bytesAvailable() > 0) {
221 continue;
222 }
223 else {
224 break;
225 }
226 }
227 }
228 /// delete socket;
229
230 allTables.insert(casterHost, allLines);
231 return success;
232}
233
234// Read Table from Caster
235////////////////////////////////////////////////////////////////////////////
236void bncTableDlg::slotGetTable() {
237
238 _buttonGet->setEnabled(false);
239
240 _allLines.clear();
241
242 if ( getFullTable(_casterHostLineEdit->currentText(),
243 _casterPortLineEdit->text().toInt(),
244 _ntripVersionComboBox->currentText().toAscii(),
245 _allLines) != success ) {
246 QMessageBox::warning(0, "BNC", "Cannot retrieve table of data");
247 _buttonGet->setEnabled(true);
248 return;
249 }
250
251 QStringList lines;
252 QStringListIterator it(_allLines);
253 while (it.hasNext()) {
254 QString line = it.next();
255 if (line.indexOf("STR") == 0) {
256 lines.push_back(line);
257 }
258 }
259
260 static const QStringList labels = QString("mountpoint,identifier,format,"
261 "format-details,carrier,system,network,country,latitude,longitude,"
262 "nmea,solution,generator,compress.,authentic.,fee,bitrate,"
263 "misc").split(",");
264
265 if (lines.size() > 0) {
266 _table->setSelectionMode(QAbstractItemView::ExtendedSelection);
267 _table->setSelectionBehavior(QAbstractItemView::SelectRows);
268
269 QStringList hlp = lines[0].split(";");
270 _table->setColumnCount(hlp.size()-1);
271 _table->setRowCount(lines.size());
272
273 QListIterator<QString> it(lines);
274 int nRow = -1;
275 while (it.hasNext()) {
276 QStringList columns = it.next().split(";");
277 ++nRow;
278 for (int ic = 0; ic < columns.size()-1; ic++) {
279
280 if (ic+1 == 11) { if (columns[ic+1] == "0") { columns[ic+1] = "no"; } else { columns[ic+1] = "yes"; }}
281
282 QTableWidgetItem* it = new QTableWidgetItem(columns[ic+1]);
283 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
284 _table->setItem(nRow, ic, it);
285 }
286 }
287 _table->sortItems(0);
288 _table->setHorizontalHeaderLabels(labels);
289 _table->setSortingEnabled(true);
290
291 int ww = QFontMetrics(this->font()).width('w');
292 _table->horizontalHeader()->resizeSection(0,10*ww);
293 _table->horizontalHeader()->resizeSection(2,8*ww);
294 _table->horizontalHeader()->resizeSection(3,15*ww);
295 _table->horizontalHeader()->resizeSection(4,8*ww);
296 _table->horizontalHeader()->resizeSection(5,8*ww);
297 _table->horizontalHeader()->resizeSection(6,8*ww);
298 _table->horizontalHeader()->resizeSection(7,8*ww);
299 _table->horizontalHeader()->resizeSection(8,8*ww);
300 _table->horizontalHeader()->resizeSection(9,8*ww);
301 _table->horizontalHeader()->resizeSection(10,8*ww);
302 _table->horizontalHeader()->resizeSection(11,8*ww);
303 _table->horizontalHeader()->resizeSection(12,15*ww);
304 _table->horizontalHeader()->resizeSection(13,8*ww);
305 _table->horizontalHeader()->resizeSection(14,8*ww);
306 _table->horizontalHeader()->resizeSection(15,8*ww);
307 _table->horizontalHeader()->resizeSection(16,8*ww);
308 _table->horizontalHeader()->resizeSection(17,15*ww);
309 }
310}
311
312// Accept slot
313////////////////////////////////////////////////////////////////////////////
314void bncTableDlg::accept() {
315
316 QSettings settings;
317 settings.setValue("casterHost", _casterHostLineEdit->currentText());
318 QStringList casterHostList;
319 for (int ii = 0; ii < _casterHostLineEdit->count(); ii++) {
320 casterHostList.push_back(_casterHostLineEdit->itemText(ii));
321 }
322 settings.setValue("casterHostList", casterHostList);
323 settings.setValue("casterPort", _casterPortLineEdit->text());
324 settings.setValue("ntripVersion", _ntripVersionComboBox->currentText());
325 settings.setValue("casterUser", _casterUserLineEdit->text());
326 settings.setValue("casterPassword", _casterPasswordLineEdit->text());
327
328 QStringList* mountPoints = new QStringList;
329
330 if (_table) {
331 for (int ir = 0; ir < _table->rowCount(); ir++) {
332 QTableWidgetItem* item = _table->item(ir,0);
333 QString format = _table->item(ir,2)->text();
334 QString latitude = _table->item(ir,8)->text();
335 QString longitude = _table->item(ir,9)->text();
336 QString nmea = _table->item(ir,10)->text();
337 QString ntripVersion = _ntripVersionComboBox->currentText();
338 format.replace(" ", "_");
339 if (_table->isItemSelected(item)) {
340 QUrl url;
341 url.setUserName(QUrl::toPercentEncoding(_casterUserLineEdit->text()));
342 url.setPassword(QUrl::toPercentEncoding(_casterPasswordLineEdit->text()));
343 url.setHost(_casterHostLineEdit->currentText());
344 url.setPort(_casterPortLineEdit->text().toInt());
345 url.setPath(item->text());
346
347 mountPoints->push_back(url.toString() + " " + format + " " + latitude
348 + " " + longitude + " " + nmea + " " + ntripVersion);
349 }
350 }
351 }
352 emit newMountPoints(mountPoints);
353
354 QDialog::accept();
355}
356
357// User changed the selection of mountPoints
358////////////////////////////////////////////////////////////////////////////
359void bncTableDlg::slotSelectionChanged() {
360 if (_table->selectedItems().isEmpty()) {
361 }
362}
363
364// Create RINEX skeleton header
365////////////////////////////////////////////////////////////////////////////
366void bncTableDlg::slotSkl() {
367
368 int nRows = _table->rowCount();
369 for (int iRow = 0; iRow < nRows; iRow++) {
370 if (_table->isItemSelected(_table->item(iRow,1))) {
371 QString staID = _table->item(iRow,0)->text();
372 QString net = _table->item(iRow,6)->text();
373
374 QString ftpDir;
375 QStringListIterator it(_allLines);
376 while (it.hasNext()) {
377 QString line = it.next();
378 if (line.indexOf("NET") == 0) {
379 QStringList tags = line.split(';');
380 if (tags.at(1) == net) {
381 ftpDir = tags.at(6);
382 break;
383 }
384 }
385 }
386
387 if (!ftpDir.isEmpty()) {
388 QUrl url(ftpDir);
389 QMessageBox::warning(0, "Warning", url.host() + "\n" + url.path() +
390 "\nnot yet implemented");
391 }
392 }
393 }
394}
395
396// Whats This Help
397void bncTableDlg::slotWhatsThis() {
398QWhatsThis::enterWhatsThisMode();
399}
400
401
Note: See TracBrowser for help on using the repository browser.