Skip to content

Commit 8eb726b

Browse files
author
homann
committed
Extended GPS plugin with a tab for performing conversions of GPX files, with the help of gpsbabel. Requested in #648.
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@7777 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent d61115d commit 8eb726b

File tree

5 files changed

+274
-31
lines changed

5 files changed

+274
-31
lines changed

src/plugins/gps_importer/qgsgpsplugin.cpp

+79-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include "qgsdataprovider.h"
2828
#include "qgsvectordataprovider.h"
2929
#include "qgsgpsplugin.h"
30-
30+
#include "qgslogger.h"
3131

3232
#include <QFileDialog>
3333
#include <QMessageBox>
@@ -137,6 +137,10 @@ void QgsGPSPlugin::run()
137137
bool, bool, QString, QString)),
138138
this, SLOT(importGPSFile(QString, QgsBabelFormat*, bool, bool,
139139
bool, QString, QString)));
140+
connect(myPluginGui, SIGNAL(convertGPSFile(QString, int,
141+
QString, QString)),
142+
this, SLOT(convertGPSFile(QString, int,
143+
QString, QString)));
140144
connect(myPluginGui, SIGNAL(downloadFromGPS(QString, QString, bool, bool,
141145
bool, QString, QString)),
142146
this, SLOT(downloadFromGPS(QString, QString, bool, bool, bool,
@@ -286,6 +290,80 @@ void QgsGPSPlugin::importGPSFile(QString inputFilename, QgsBabelFormat* importer
286290
}
287291

288292

293+
void QgsGPSPlugin::convertGPSFile(QString inputFilename,
294+
int convertType,
295+
QString outputFilename,
296+
QString layerName) {
297+
298+
// what features does the user want to import?
299+
300+
QStringList convertStrings;
301+
302+
switch ( convertType )
303+
{
304+
case 0:
305+
convertStrings << "-x" << "transform,wpt=rte,del"; break;
306+
case 1:
307+
convertStrings << "-x" << "transform,rte=wpt,del"; break;
308+
default:
309+
QgsDebugMsg("Illegal conversion index!");
310+
return;
311+
}
312+
313+
// try to start the gpsbabel process
314+
QStringList babelArgs;
315+
babelArgs << mBabelPath << "-i"<<"gpx"<<"-f"<< inputFilename
316+
<< convertStrings <<"-o"<<"gpx"<<"-F"<< outputFilename;
317+
QgsDebugMsg(QString("Conversion command: ") + babelArgs.join("_"));
318+
319+
Q3Process babelProcess(babelArgs);
320+
if (!babelProcess.start()) {
321+
QMessageBox::warning(NULL, tr("Could not start process"),
322+
tr("Could not start GPSBabel!"));
323+
return;
324+
}
325+
326+
// wait for gpsbabel to finish (or the user to cancel)
327+
Q3ProgressDialog progressDialog(tr("Importing data..."), tr("Cancel"), 0,
328+
NULL, 0, true);
329+
progressDialog.show();
330+
for (int i = 0; babelProcess.isRunning(); ++i) {
331+
QCoreApplication::processEvents();
332+
333+
progressDialog.setProgress(i/64);
334+
if (progressDialog.wasCanceled())
335+
return;
336+
}
337+
338+
// did we get any data?
339+
if (babelProcess.exitStatus() != 0) {
340+
QString babelError(babelProcess.readStderr());
341+
QString errorMsg(tr("Could not convert data from %1!\n\n")
342+
.arg(inputFilename));
343+
errorMsg += babelError;
344+
QMessageBox::warning(NULL, tr("Error converting data"), errorMsg);
345+
return;
346+
}
347+
348+
// add the layer
349+
switch ( convertType )
350+
{
351+
case 0:
352+
emit drawVectorLayer(outputFilename + "?type=waypoint",
353+
layerName, "gpx");
354+
break;
355+
case 1:
356+
emit drawVectorLayer(outputFilename + "?type=route",
357+
layerName, "gpx");
358+
break;
359+
default:
360+
QgsDebugMsg("Illegal conversion index!");
361+
return;
362+
}
363+
364+
emit closeGui();
365+
}
366+
289367
void QgsGPSPlugin::downloadFromGPS(QString device, QString port,
290368
bool downloadWaypoints, bool downloadRoutes,
291369
bool downloadTracks, QString outputFilename,

src/plugins/gps_importer/qgsgpsplugin.h

+4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ public slots:
6363
bool importWaypoints, bool importRoutes,
6464
bool importTracks, QString outputFilename,
6565
QString layerName);
66+
void convertGPSFile(QString inputFilename,
67+
int convertType,
68+
QString outputFilename,
69+
QString layerName);
6670
void downloadFromGPS(QString device, QString port,
6771
bool downloadWaypoints, bool downloadRoutes,
6872
bool downloadTracks, QString outputFilename,

src/plugins/gps_importer/qgsgpsplugingui.cpp

+76-29
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ QgsGPSPluginGui::QgsGPSPluginGui(const BabelMap& importers,
3737
populatePortComboBoxes();
3838
populateULLayerComboBox();
3939
populateIMPBabelFormats();
40+
populateCONVDialog();
4041

4142
connect(pbULEditDevices, SIGNAL(clicked()), this, SLOT(openDeviceEditor()));
4243
connect(pbDLEditDevices, SIGNAL(clicked()), this, SLOT(openDeviceEditor()));
@@ -53,6 +54,12 @@ QgsGPSPluginGui::QgsGPSPluginGui(const BabelMap& importers,
5354
this, SLOT(enableRelevantControls()));
5455
connect(leIMPLayer, SIGNAL(textChanged(const QString&)),
5556
this, SLOT(enableRelevantControls()));
57+
connect(leCONVInput, SIGNAL(textChanged(const QString&)),
58+
this, SLOT(enableRelevantControls()));
59+
connect(leCONVOutput, SIGNAL(textChanged(const QString&)),
60+
this, SLOT(enableRelevantControls()));
61+
connect(leCONVLayer, SIGNAL(textChanged(const QString&)),
62+
this, SLOT(enableRelevantControls()));
5663
connect(leDLOutput, SIGNAL(textChanged(const QString&)),
5764
this, SLOT(enableRelevantControls()));
5865
connect(leDLBasename, SIGNAL(textChanged(const QString&)),
@@ -74,38 +81,14 @@ void QgsGPSPluginGui::on_buttonBox_accepted()
7481
{
7582

7683
// what should we do?
77-
switch (tabWidget->currentPageIndex()) {
84+
switch (tabWidget->currentPageIndex())
85+
{
7886
// add a GPX layer?
7987
case 0:
8088
emit loadGPXFile(leGPXFile->text(), cbGPXWaypoints->isChecked(),
8189
cbGPXRoutes->isChecked(), cbGPXTracks->isChecked());
8290
break;
8391

84-
// or import a download file?
85-
/*
86-
case 666:
87-
//check input file exists
88-
//
89-
if (!QFile::exists ( leInputFile->text() ))
90-
{
91-
QMessageBox::warning( this, "GPS Importer",
92-
"Unable to find the input file.\n"
93-
"Please reselect a valid file." );
94-
return;
95-
}
96-
WayPointToShape * myWayPointToShape = new WayPointToShape(leOutputShapeFile->text(),leInputFile->text());
97-
//
98-
// If you have a produced a raster layer using your plugin, you can ask qgis to
99-
// add it to the view using:
100-
// emit drawRasterLayer(QString("layername"));
101-
// or for a vector layer
102-
// emit drawVectorLayer(QString("pathname"),QString("layername"),QString("provider name (either ogr or postgres"));
103-
//
104-
delete myWayPointToShape;
105-
emit drawVectorLayer(leOutputShapeFile->text(),QString("Waypoints"),QString("ogr"));
106-
break;
107-
*/
108-
10992
// or import other file?
11093
case 1: {
11194
const QString& typeString(cmbDLFeatureType->currentText());
@@ -116,7 +99,6 @@ void QgsGPSPluginGui::on_buttonBox_accepted()
11699
leIMPLayer->text());
117100
break;
118101
}
119-
120102
// or download GPS data from a device?
121103
case 2: {
122104
int featureType = cmbDLFeatureType->currentItem();
@@ -125,13 +107,22 @@ void QgsGPSPluginGui::on_buttonBox_accepted()
125107
leDLOutput->text(), leDLBasename->text());
126108
break;
127109
}
128-
129110
// or upload GPS data to a device?
130-
case 3:
111+
case 3: {
131112
emit uploadToGPS(mGPXLayers[cmbULLayer->currentItem()],
132113
cmbULDevice->currentText(), cmbULPort->currentText());
133114
break;
134115
}
116+
// or convert between waypoints/tracks=
117+
case 4: {
118+
int convertType = cmbCONVType->currentItem();
119+
emit convertGPSFile(leCONVInput->text(),
120+
convertType,
121+
leCONVOutput->text(),
122+
leCONVLayer->text());
123+
break;
124+
}
125+
}
135126
accept();
136127
}
137128

@@ -200,6 +191,16 @@ void QgsGPSPluginGui::enableRelevantControls()
200191
else
201192
pbnOK->setEnabled(true);
202193
}
194+
195+
// convert between waypoint/routes
196+
else if (tabWidget->currentPageIndex() == 4) {
197+
198+
if ((leCONVInput->text() == "") || (leCONVOutput->text() == "") ||
199+
(leCONVLayer->text() == ""))
200+
pbnOK->setEnabled(false);
201+
else
202+
pbnOK->setEnabled(true);
203+
}
203204
}
204205

205206

@@ -400,6 +401,52 @@ void QgsGPSPluginGui::populateIMPBabelFormats() {
400401
cmbDLDevice->setCurrentItem(d);
401402
}
402403

404+
void QgsGPSPluginGui::populateCONVDialog() {
405+
cmbCONVType->insertItem(tr("Route -> Waypoint"));
406+
cmbCONVType->insertItem(tr("Waypoint -> Route"));
407+
QString format = QString("<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\"> p, li { white-space: pre-wrap; } </style></head><body style=\" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;\"><p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Arial'; font-size:12pt;\"><span style=\" font-size:10pt;\">"\
408+
"%1"\
409+
"</span><a href=\"http://gpsbabel.sf.net\"><span style=\" font-size:10pt; text-decoration: underline; color:#0000ff;\">http://gpsbabel.sf.net</span></a><span style=\" font-size:10pt;\">"\
410+
"%2"\
411+
"</span></p><p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Arial'; font-size:10pt;\">"\
412+
"%3"\
413+
"</p></body></html>");
414+
QString text = format
415+
.arg(tr("QGIS can perform conversions of GPX files, by using GPSBabel ("))
416+
.arg(tr(") to perform the conversions. This requires that you have GPSBabel installed where QGIS can find it."))
417+
.arg(tr("Select a GPX input file name, the type of conversion you want to perform, a GPX filename that you want to save the converted file as, and a name for the new layer created from the result."));
418+
419+
teCONVDescription->setHtml(text);
420+
QgsDebugMsg(text);
421+
}
422+
423+
void QgsGPSPluginGui::on_pbnCONVInput_clicked()
424+
{
425+
QString myFileTypeQString;
426+
QString myFilterString=tr("GPS eXchange format (*.gpx)");
427+
QSettings settings;
428+
QString dir = settings.readEntry("/Plugin-GPS/gpxdirectory");
429+
if (dir.isEmpty())
430+
dir = ".";
431+
QString myFileNameQString = QFileDialog::getOpenFileName(
432+
this, //parent dialog
433+
tr("Select GPX file"), //caption
434+
dir, //initial dir
435+
myFilterString, //filters to select
436+
&myFileTypeQString); //the pointer to store selected filter
437+
if (!myFileNameQString.isEmpty())
438+
leCONVInput->setText(myFileNameQString);
439+
}
440+
441+
void QgsGPSPluginGui::on_pbnCONVOutput_clicked() {
442+
QString myFileNameQString =
443+
QFileDialog::getSaveFileName(this, //parent dialog
444+
tr("Choose a filename to save under"),
445+
".", //initial dir
446+
tr("GPS eXchange format (*.gpx)"));
447+
if (!myFileNameQString.isEmpty())
448+
leCONVOutput->setText(myFileNameQString);
449+
}
403450

404451
void QgsGPSPluginGui::openDeviceEditor() {
405452
QgsGPSDeviceDialog* dlg = new QgsGPSDeviceDialog(mDevices);

src/plugins/gps_importer/qgsgpsplugingui.h

+8
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ public slots:
5151

5252
void on_pbnIMPInput_clicked();
5353
void on_pbnIMPOutput_clicked();
54+
55+
void on_pbnCONVInput_clicked();
56+
void on_pbnCONVOutput_clicked();
5457

5558
void on_pbnDLOutput_clicked();
5659

@@ -60,6 +63,7 @@ public slots:
6063
void populateULLayerComboBox();
6164
void populateIMPBabelFormats();
6265
void populatePortComboBoxes();
66+
void populateCONVDialog();
6367

6468
private slots:
6569

@@ -76,6 +80,10 @@ private slots:
7680
bool importWaypoints, bool importRoutes,
7781
bool importTracks, QString outputFilename,
7882
QString layerName);
83+
void convertGPSFile(QString inputFilename,
84+
int convertType,
85+
QString outputFilename,
86+
QString layerName);
7987
void downloadFromGPS(QString device, QString port, bool downloadWaypoints,
8088
bool downloadRoutes, bool downloadTracks,
8189
QString outputFilename, QString layerName);

0 commit comments

Comments
 (0)