1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2013 Mohammed Nafees <nafees.technocool@gmail.com>
4 
5 #include "GpsbabelRunner.h"
6 
7 #include "GeoDataParser.h"
8 #include "GeoDataDocument.h"
9 #include "MarbleDebug.h"
10 
11 #include <QFile>
12 #include <QProcess>
13 #include <QFileInfo>
14 #include <QTemporaryFile>
15 #include <QDir>
16 #include <QMap>
17 
18 namespace Marble
19 {
20 
GpsbabelRunner(QObject * parent)21 GpsbabelRunner::GpsbabelRunner( QObject *parent ) :
22     ParsingRunner( parent )
23 {
24 }
25 
parseFile(const QString & fileName,DocumentRole role,QString & error)26 GeoDataDocument *GpsbabelRunner::parseFile(const QString &fileName, DocumentRole role, QString &error)
27 {
28     // Check and see if the file exists
29     if ( !QFileInfo( fileName ).exists() ) {
30         error = QStringLiteral("File %1 does not exist").arg(fileName);
31         mDebug() << error;
32         return nullptr;
33     }
34 
35     // Inspect the filename suffix
36     QString const fileSuffix = QFileInfo( fileName ).suffix();
37 
38     // Determine if fileName suffix is supported by this plugin
39     QMap<QString,QString> fileTypes;
40     fileTypes["nmea"]     = "nmea";
41     fileTypes["igc"]      = "igc";
42     fileTypes["tiger"]    = "tiger";
43     fileTypes["ov2"]      = "tomtom";
44     fileTypes["garmin"]   = "garmin_txt";
45     fileTypes["magellan"] = "magellan";
46     fileTypes["csv"]      = "csv";
47     QString const inputFileType = fileTypes[fileSuffix];
48     if ( inputFileType.isEmpty() ) {
49         error = QStringLiteral("Unsupported file extension for").arg(fileName);
50         mDebug() << error;
51         return nullptr;
52     }
53 
54     // Set up temporary file to hold output KML from gpsbabel executable
55     QTemporaryFile tempKmlFile(QDir::tempPath() + QLatin1String("/marble-gpsbabel-XXXXXX.kml"));
56     tempKmlFile.open();
57     QFile kmlFile( tempKmlFile.fileName() );
58 
59     // Set up gpsbabel command line
60     const QString command = QLatin1String("gpsbabel");
61     const QStringList args = QStringList()
62         << QLatin1String("-i")
63         << inputFileType
64         << QLatin1String("-f")
65         << fileName
66         << QLatin1String("-o")
67         << QLatin1String("kml")
68         << QLatin1String("-F")
69         << tempKmlFile.fileName()
70     ;
71 
72     // Execute gpsbabel to parse the input file
73     int const exitStatus = QProcess::execute( command, args );
74     if ( exitStatus == 0 ) {
75         kmlFile.open( QIODevice::ReadWrite );
76         GeoDataParser parser( GeoData_KML );
77         parser.read( &kmlFile );
78         GeoDataDocument *document = dynamic_cast<GeoDataDocument*>( parser.releaseDocument() );
79         if ( !document ) {
80             error = parser.errorString();
81             mDebug() << error;
82             return nullptr;
83         }
84 
85         document->setDocumentRole( role );
86         return document;
87     } else {
88         error = QStringLiteral("Gpsbabel returned error code %1").arg(exitStatus);
89         mDebug() << error;
90         return nullptr;
91     }
92 }
93 
94 }
95 
96 #include "moc_GpsbabelRunner.cpp"
97