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

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