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

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

* empty log message *

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