File indexing completed on 2024-04-28 03:50:29

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2011 Thibaut Gridel <tgridel@free.fr>
0004 
0005 #include "CacheRunner.h"
0006 
0007 #include "GeoDataDocument.h"
0008 #include "GeoDataExtendedData.h"
0009 #include "GeoDataData.h"
0010 #include "GeoDataPlacemark.h"
0011 #include "MarbleDebug.h"
0012 
0013 #include <QFile>
0014 #include <QDataStream>
0015 #include <QSet>
0016 
0017 namespace Marble
0018 {
0019 
0020 const quint32 MarbleMagicNumber = 0x31415926;
0021 
0022 CacheRunner::CacheRunner(QObject *parent) :
0023     ParsingRunner(parent)
0024 {
0025 }
0026 
0027 CacheRunner::~CacheRunner()
0028 {
0029 }
0030 
0031 GeoDataDocument* CacheRunner::parseFile( const QString &fileName, DocumentRole role, QString& error )
0032 {
0033     QFile file( fileName );
0034     if ( !file.exists() ) {
0035         error = QStringLiteral("File %1 does not exist").arg(fileName);
0036         mDebug() << error;
0037         return nullptr;
0038     }
0039 
0040     file.open( QIODevice::ReadOnly );
0041     QDataStream in( &file );
0042 
0043     // Read and check the header
0044     quint32 magic;
0045     in >> magic;
0046     if ( magic != MarbleMagicNumber ) {
0047         return nullptr;
0048     }
0049 
0050     // Read the version
0051     qint32 version;
0052     in >> version;
0053     if ( version < 015 ) {
0054         error = QStringLiteral("Bad cache file %1: Version %2 is too old, need 15 or later").arg(fileName).arg(version);
0055         mDebug() << error;
0056         return nullptr;
0057     }
0058     /*
0059       if (version > 002) {
0060       qDebug( "Bad file - too new!" );
0061       return;
0062       }
0063     */
0064     GeoDataDocument *document = new GeoDataDocument();
0065     document->setDocumentRole( role );
0066 
0067     in.setVersion( QDataStream::Qt_4_2 );
0068 
0069     // Read the data itself
0070     // Use double to provide a single cache file format across architectures
0071     double   lon;
0072     double   lat;
0073     double   alt;
0074     double   area;
0075 
0076     QString  tmpstr;
0077     qint64   tmpint64;
0078     qint8    tmpint8;
0079     qint16   tmpint16;
0080 
0081     // share string data on the heap at least for this file
0082     QSet<QString> stringPool;
0083     const QString gmtId = QStringLiteral("gmt");
0084     const QString dstId = QStringLiteral("dst");
0085 
0086     while ( !in.atEnd() ) {
0087         GeoDataPlacemark *mark = new GeoDataPlacemark;
0088         in >> tmpstr; tmpstr = *stringPool.insert(tmpstr);
0089         mark->setName( tmpstr );
0090         in >> lon >> lat >> alt;
0091         mark->setCoordinate( (qreal)(lon), (qreal)(lat), (qreal)(alt) );
0092         in >> tmpstr; tmpstr = *stringPool.insert(tmpstr);
0093         mark->setRole( tmpstr );
0094         in >> tmpstr; tmpstr = *stringPool.insert(tmpstr);
0095         mark->setDescription( tmpstr );
0096         in >> tmpstr; tmpstr = *stringPool.insert(tmpstr);
0097         mark->setCountryCode( tmpstr );
0098         in >> tmpstr; tmpstr = *stringPool.insert(tmpstr);
0099         mark->setState( tmpstr );
0100         in >> area;
0101         mark->setArea( (qreal)(area) );
0102         in >> tmpint64;
0103         mark->setPopulation( tmpint64 );
0104         in >> tmpint16;
0105         mark->extendedData().addValue(GeoDataData(gmtId, int(tmpint16)));
0106         in >> tmpint8;
0107         mark->extendedData().addValue(GeoDataData(dstId, int(tmpint8)));
0108 
0109         document->append( mark );
0110     }
0111     document->setFileName( fileName );
0112 
0113     file.close();
0114     return document;
0115 }
0116 
0117 }
0118 
0119 #include "moc_CacheRunner.cpp"