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

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