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

Last change on this file since 1273 was 1273, checked in by zdenek, 15 years ago

* empty log message *

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