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

Last change on this file since 1350 was 1350, checked in by mervart, 16 years ago

* empty log message *

File size: 15.4 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, QStringList& allLines,
149 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 QByteArray _latitude;
172 QByteArray _longitude;
173 QByteArray _nmea;
174 bncSocket* socket = new bncSocket();
175 if (socket->request(url, _latitude, _longitude,
176 _nmea, 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 socket->waitForReadyRead(timeOut);
217 if (socket->bytesAvailable() > 0) {
218 continue;
219 }
220 else {
221 break;
222 }
223 }
224 }
225 delete socket;
226
227 allTables.insert(casterHost, allLines);
228 return success;
229}
230
231// Read Table from Caster
232////////////////////////////////////////////////////////////////////////////
233void bncTableDlg::slotGetTable() {
234
235 _buttonGet->setEnabled(false);
236
237 _allLines.clear();
238
239 if ( getFullTable(_casterHostLineEdit->currentText(),
240 _casterPortLineEdit->text().toInt(),
241 _allLines) != success ) {
242 QMessageBox::warning(0, "BNC", "Cannot retrieve table of data");
243 _buttonGet->setEnabled(true);
244 return;
245 }
246
247 QStringList lines;
248 QStringListIterator it(_allLines);
249 while (it.hasNext()) {
250 QString line = it.next();
251 if (line.indexOf("STR") == 0) {
252 lines.push_back(line);
253 }
254 }
255
256 static const QStringList labels = QString("mountpoint,identifier,format,"
257 "format-details,carrier,system,network,country,latitude,longitude,"
258 "nmea,solution,generator,compress.,authentic.,fee,bitrate,"
259 "misc").split(",");
260
261 if (lines.size() > 0) {
262 _table->setSelectionMode(QAbstractItemView::ExtendedSelection);
263 _table->setSelectionBehavior(QAbstractItemView::SelectRows);
264
265 QStringList hlp = lines[0].split(";");
266 _table->setColumnCount(hlp.size()-1);
267 _table->setRowCount(lines.size());
268
269 QListIterator<QString> it(lines);
270 int nRow = -1;
271 while (it.hasNext()) {
272 QStringList columns = it.next().split(";");
273 ++nRow;
274 for (int ic = 0; ic < columns.size()-1; ic++) {
275
276 if (ic+1 == 11) { if (columns[ic+1] == "0") { columns[ic+1] = "no"; } else { columns[ic+1] = "yes"; }}
277
278 QTableWidgetItem* it = new QTableWidgetItem(columns[ic+1]);
279 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
280 _table->setItem(nRow, ic, it);
281 }
282 }
283 _table->sortItems(0);
284 _table->setHorizontalHeaderLabels(labels);
285 _table->setSortingEnabled(true);
286
287 int ww = QFontMetrics(this->font()).width('w');
288 _table->horizontalHeader()->resizeSection(0,10*ww);
289 _table->horizontalHeader()->resizeSection(2,8*ww);
290 _table->horizontalHeader()->resizeSection(3,15*ww);
291 _table->horizontalHeader()->resizeSection(4,8*ww);
292 _table->horizontalHeader()->resizeSection(5,8*ww);
293 _table->horizontalHeader()->resizeSection(6,8*ww);
294 _table->horizontalHeader()->resizeSection(7,8*ww);
295 _table->horizontalHeader()->resizeSection(8,8*ww);
296 _table->horizontalHeader()->resizeSection(9,8*ww);
297 _table->horizontalHeader()->resizeSection(10,8*ww);
298 _table->horizontalHeader()->resizeSection(11,8*ww);
299 _table->horizontalHeader()->resizeSection(12,15*ww);
300 _table->horizontalHeader()->resizeSection(13,8*ww);
301 _table->horizontalHeader()->resizeSection(14,8*ww);
302 _table->horizontalHeader()->resizeSection(15,8*ww);
303 _table->horizontalHeader()->resizeSection(16,8*ww);
304 _table->horizontalHeader()->resizeSection(17,15*ww);
305 }
306}
307
308// Accept slot
309////////////////////////////////////////////////////////////////////////////
310void bncTableDlg::accept() {
311
312 QSettings settings;
313 settings.setValue("casterHost", _casterHostLineEdit->currentText());
314 QStringList casterHostList;
315 for (int ii = 0; ii < _casterHostLineEdit->count(); ii++) {
316 casterHostList.push_back(_casterHostLineEdit->itemText(ii));
317 }
318 settings.setValue("casterHostList", casterHostList);
319 settings.setValue("casterPort", _casterPortLineEdit->text());
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 format.replace(" ", "_");
333 if (_table->isItemSelected(item)) {
334 QUrl url;
335 url.setUserName(QUrl::toPercentEncoding(_casterUserLineEdit->text()));
336 url.setPassword(QUrl::toPercentEncoding(_casterPasswordLineEdit->text()));
337 url.setHost(_casterHostLineEdit->currentText());
338 url.setPort(_casterPortLineEdit->text().toInt());
339 url.setPath(item->text());
340
341 mountPoints->push_back(url.toString() + " " + format + " " + latitude + " " + longitude + " " + nmea);
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.