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

Last change on this file since 1278 was 1274, checked in by zdenek, 16 years ago

* empty log message *

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