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

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

* empty log message *

File size: 15.6 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 "bnctabledlg.h"
42#include "bncgetthread.h"
43#include "bncsocket.h"
44
45// Constructor
46////////////////////////////////////////////////////////////////////////////
47bncTableDlg::bncTableDlg(QWidget* parent) : QDialog(parent) {
48
49 setMinimumSize(600,400);
50 setWindowTitle(tr("Add Mountpoints"));
51
52 QVBoxLayout* mainLayout = new QVBoxLayout(this);
53
54 QSettings settings;
55 _casterHostLineEdit = new QComboBox();
56 _casterHostLineEdit->setDuplicatesEnabled(false);
57 _casterHostLineEdit->setEditable(true);
58 int ww = QFontMetrics(_casterHostLineEdit->font()).width('w');
59 _casterHostLineEdit->setMaximumWidth(20*ww);
60 QStringList casterHostList = settings.value("casterHostList").toStringList();
61 _casterHostLineEdit->addItem(settings.value("casterHost").toString());
62 for (int ii = 0; ii < casterHostList.count(); ii++) {
63 QString item = casterHostList[ii];
64 if (_casterHostLineEdit->findText(item, Qt::MatchFixedString) < 0) {
65 _casterHostLineEdit->addItem(item);
66 }
67 }
68 _casterPortLineEdit = new QLineEdit(settings.value("casterPort").toString());
69 _casterPortLineEdit->setMaximumWidth(9*ww);
70 _casterUserLineEdit = new QLineEdit(settings.value("casterUser").toString());
71 _casterUserLineEdit->setMaximumWidth(9*ww);
72 _casterPasswordLineEdit = new QLineEdit(settings.value("casterPassword").toString());
73 _casterPasswordLineEdit->setMaximumWidth(9*ww);
74 _casterPasswordLineEdit->setEchoMode(QLineEdit::Password);
75
76 _ntripVersionComboBox = new QComboBox();
77 _ntripVersionComboBox->addItems(QString("1,2,AUTO").split(","));
78 int kk = _ntripVersionComboBox->findText(settings.value("ntripVersion").toString());
79 if (kk != -1) {
80 _ntripVersionComboBox->setCurrentIndex(kk);
81 }
82
83 // WhatsThis
84 // ---------
85 _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>."));
86 _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>."));
87 _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>."));
88 _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>."));
89
90 QGridLayout* editLayout = new QGridLayout;
91 editLayout->addWidget(new QLabel(tr("Caster host")), 0, 0);
92 editLayout->addWidget(_casterHostLineEdit, 0, 1);
93 editLayout->addWidget(new QLabel(tr("Caster port")), 0, 2);
94 editLayout->addWidget(_casterPortLineEdit, 0, 3);
95 editLayout->addWidget(new QLabel(tr("NTRIP Version")), 0, 4);
96 editLayout->addWidget(_ntripVersionComboBox, 0, 5);
97 editLayout->addWidget(new QLabel(tr("User")), 1, 0);
98 editLayout->addWidget(_casterUserLineEdit, 1, 1);
99 editLayout->addWidget(new QLabel(tr("Password")), 1, 2);
100 editLayout->addWidget(_casterPasswordLineEdit, 1, 3);
101
102 mainLayout->addLayout(editLayout);
103
104 _table = new QTableWidget(this);
105 _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>"));
106 connect(_table, SIGNAL(itemSelectionChanged()),
107 this, SLOT(slotSelectionChanged()));
108 mainLayout->addWidget(_table);
109
110 _buttonWhatsThis = new QPushButton(tr("Help=Shift+F1"), this);
111 connect(_buttonWhatsThis, SIGNAL(clicked()), this, SLOT(slotWhatsThis()));
112
113 _buttonGet = new QPushButton(tr("Get table"), this);
114 _buttonGet->setDefault(true);
115 connect(_buttonGet, SIGNAL(clicked()), this, SLOT(slotGetTable()));
116
117 _buttonCancel = new QPushButton(tr("Cancel"), this);
118 connect(_buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
119
120 _buttonOK = new QPushButton(tr("OK"), this);
121 connect(_buttonOK, SIGNAL(clicked()), this, SLOT(accept()));
122
123 QHBoxLayout* buttonLayout = new QHBoxLayout;
124 buttonLayout->addWidget(_buttonWhatsThis);
125 buttonLayout->addStretch(1);
126 buttonLayout->addWidget(_buttonGet);
127 buttonLayout->addWidget(_buttonCancel);
128 buttonLayout->addWidget(_buttonOK);
129
130 mainLayout->addLayout(buttonLayout);
131}
132
133// Destructor
134////////////////////////////////////////////////////////////////////////////
135bncTableDlg::~bncTableDlg() {
136 if (_table) {
137 for (int ir = 0; ir < _table->rowCount(); ir++) {
138 for (int ic = 0; ic < _table->columnCount(); ic++) {
139 delete _table->item(ir,ic);
140 }
141 }
142 }
143}
144
145// Read Table the caster (static)
146////////////////////////////////////////////////////////////////////////////
147t_irc bncTableDlg::getFullTable(const QString& casterHost,
148 int casterPort, const QByteArray& ntripVersion,
149 QStringList& allLines, bool alwaysRead) {
150
151 static QMutex mutex;
152 static QMap<QString, QStringList> allTables;
153
154 QMutexLocker locker(&mutex);
155
156 if (!alwaysRead && allTables.find(casterHost) != allTables.end()) {
157 allLines = allTables.find(casterHost).value();
158 return success;
159 }
160
161 allLines.clear();
162
163 QUrl url;
164 url.setHost(casterHost);
165 url.setPort(casterPort);
166
167 // Send the Request
168 // ----------------
169 const int timeOut = 10*1000;
170 QString msg;
171 bncSocket* socket = new bncSocket();
172 if (socket->request(url, "", "", "", ntripVersion, timeOut, msg) != success) {
173 delete socket;
174 return failure;
175 }
176
177 // Read Caster Response
178 // --------------------
179 bool proxyRespond = false;
180 bool first = true;
181 while (true) {
182 if (socket->canReadLine()) {
183 QString line = socket->readLine();
184
185 // Skip messages from proxy server
186 // -------------------------------
187 if (line.indexOf("SOURCETABLE 200 OK") == -1 &&
188 line.indexOf("200 OK") != -1 ) {
189 proxyRespond = true;
190 }
191 if (proxyRespond) {
192 if (line.trimmed().isEmpty()) {
193 proxyRespond = false;
194 }
195 continue;
196 }
197
198 allLines.push_back(line);
199 if (first) {
200 first = false;
201 if (line.indexOf("SOURCETABLE 200 OK") != 0) {
202 break;
203 }
204 }
205 else {
206 if (line.indexOf("ENDSOURCETABLE") == 0) {
207 break;
208 }
209 }
210 }
211 else {
212 socket->waitForReadyRead(timeOut);
213 if (socket->bytesAvailable() > 0) {
214 continue;
215 }
216 else {
217 break;
218 }
219 }
220 }
221 delete socket;
222
223 allTables.insert(casterHost, allLines);
224 return success;
225}
226
227// Read Table from Caster
228////////////////////////////////////////////////////////////////////////////
229void bncTableDlg::slotGetTable() {
230
231 _buttonGet->setEnabled(false);
232
233 _allLines.clear();
234
235 if ( getFullTable(_casterHostLineEdit->currentText(),
236 _casterPortLineEdit->text().toInt(),
237 _ntripVersionComboBox->currentText().toAscii(),
238 _allLines) != success ) {
239 QMessageBox::warning(0, "BNC", "Cannot retrieve table of data");
240 _buttonGet->setEnabled(true);
241 return;
242 }
243
244 QStringList lines;
245 QStringListIterator it(_allLines);
246 while (it.hasNext()) {
247 QString line = it.next();
248 if (line.indexOf("STR") == 0) {
249 lines.push_back(line);
250 }
251 }
252
253 static const QStringList labels = QString("mountpoint,identifier,format,"
254 "format-details,carrier,system,network,country,latitude,longitude,"
255 "nmea,solution,generator,compress.,authentic.,fee,bitrate,"
256 "misc").split(",");
257
258 if (lines.size() > 0) {
259 _table->setSelectionMode(QAbstractItemView::ExtendedSelection);
260 _table->setSelectionBehavior(QAbstractItemView::SelectRows);
261
262 QStringList hlp = lines[0].split(";");
263 _table->setColumnCount(hlp.size()-1);
264 _table->setRowCount(lines.size());
265
266 QListIterator<QString> it(lines);
267 int nRow = -1;
268 while (it.hasNext()) {
269 QStringList columns = it.next().split(";");
270 ++nRow;
271 for (int ic = 0; ic < columns.size()-1; ic++) {
272
273 if (ic+1 == 11) { if (columns[ic+1] == "0") { columns[ic+1] = "no"; } else { columns[ic+1] = "yes"; }}
274
275 QTableWidgetItem* it = new QTableWidgetItem(columns[ic+1]);
276 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
277 _table->setItem(nRow, ic, it);
278 }
279 }
280 _table->sortItems(0);
281 _table->setHorizontalHeaderLabels(labels);
282 _table->setSortingEnabled(true);
283
284 int ww = QFontMetrics(this->font()).width('w');
285 _table->horizontalHeader()->resizeSection(0,10*ww);
286 _table->horizontalHeader()->resizeSection(2,8*ww);
287 _table->horizontalHeader()->resizeSection(3,15*ww);
288 _table->horizontalHeader()->resizeSection(4,8*ww);
289 _table->horizontalHeader()->resizeSection(5,8*ww);
290 _table->horizontalHeader()->resizeSection(6,8*ww);
291 _table->horizontalHeader()->resizeSection(7,8*ww);
292 _table->horizontalHeader()->resizeSection(8,8*ww);
293 _table->horizontalHeader()->resizeSection(9,8*ww);
294 _table->horizontalHeader()->resizeSection(10,8*ww);
295 _table->horizontalHeader()->resizeSection(11,8*ww);
296 _table->horizontalHeader()->resizeSection(12,15*ww);
297 _table->horizontalHeader()->resizeSection(13,8*ww);
298 _table->horizontalHeader()->resizeSection(14,8*ww);
299 _table->horizontalHeader()->resizeSection(15,8*ww);
300 _table->horizontalHeader()->resizeSection(16,8*ww);
301 _table->horizontalHeader()->resizeSection(17,15*ww);
302 }
303}
304
305// Accept slot
306////////////////////////////////////////////////////////////////////////////
307void bncTableDlg::accept() {
308
309 QSettings settings;
310 settings.setValue("casterHost", _casterHostLineEdit->currentText());
311 QStringList casterHostList;
312 for (int ii = 0; ii < _casterHostLineEdit->count(); ii++) {
313 casterHostList.push_back(_casterHostLineEdit->itemText(ii));
314 }
315 settings.setValue("casterHostList", casterHostList);
316 settings.setValue("casterPort", _casterPortLineEdit->text());
317 settings.setValue("ntripVersion", _ntripVersionComboBox->currentText());
318 settings.setValue("casterUser", _casterUserLineEdit->text());
319 settings.setValue("casterPassword", _casterPasswordLineEdit->text());
320
321 QStringList* mountPoints = new QStringList;
322
323 if (_table) {
324 for (int ir = 0; ir < _table->rowCount(); ir++) {
325 QTableWidgetItem* item = _table->item(ir,0);
326 QString format = _table->item(ir,2)->text();
327 QString latitude = _table->item(ir,8)->text();
328 QString longitude = _table->item(ir,9)->text();
329 QString nmea = _table->item(ir,10)->text();
330 QString ntripVersion = _ntripVersionComboBox->currentText();
331 format.replace(" ", "_");
332 if (_table->isItemSelected(item)) {
333 QUrl url;
334 url.setUserName(QUrl::toPercentEncoding(_casterUserLineEdit->text()));
335 url.setPassword(QUrl::toPercentEncoding(_casterPasswordLineEdit->text()));
336 url.setHost(_casterHostLineEdit->currentText());
337 url.setPort(_casterPortLineEdit->text().toInt());
338 url.setPath(item->text());
339
340 mountPoints->push_back(url.toString() + " " + format + " " + latitude
341 + " " + longitude + " " + nmea + " " + ntripVersion);
342 }
343 }
344 }
345 emit newMountPoints(mountPoints);
346
347 QDialog::accept();
348}
349
350// User changed the selection of mountPoints
351////////////////////////////////////////////////////////////////////////////
352void bncTableDlg::slotSelectionChanged() {
353 if (_table->selectedItems().isEmpty()) {
354 }
355}
356
357// Create RINEX skeleton header
358////////////////////////////////////////////////////////////////////////////
359void bncTableDlg::slotSkl() {
360
361 int nRows = _table->rowCount();
362 for (int iRow = 0; iRow < nRows; iRow++) {
363 if (_table->isItemSelected(_table->item(iRow,1))) {
364 QString staID = _table->item(iRow,0)->text();
365 QString net = _table->item(iRow,6)->text();
366
367 QString ftpDir;
368 QStringListIterator it(_allLines);
369 while (it.hasNext()) {
370 QString line = it.next();
371 if (line.indexOf("NET") == 0) {
372 QStringList tags = line.split(';');
373 if (tags.at(1) == net) {
374 ftpDir = tags.at(6);
375 break;
376 }
377 }
378 }
379
380 if (!ftpDir.isEmpty()) {
381 QUrl url(ftpDir);
382 QMessageBox::warning(0, "Warning", url.host() + "\n" + url.path() +
383 "\nnot yet implemented");
384 }
385 }
386 }
387}
388
389// Whats This Help
390void bncTableDlg::slotWhatsThis() {
391QWhatsThis::enterWhatsThisMode();
392}
393
394
Note: See TracBrowser for help on using the repository browser.