File indexing completed on 2024-05-12 03:50:41

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2010 Dennis Nienhüser <nienhueser@kde.org>
0004 //
0005 
0006 #include "WaypointParser.h"
0007 
0008 #include <QDebug>
0009 
0010 namespace Marble
0011 {
0012 
0013 // Template specialization to avoid shifting a QString through a QVariant and back
0014 template<>
0015 QString WaypointParser::readField<QString>( Field field, const QStringList &fields, const QString &defaultValue ) const {
0016     int index = m_fieldIndices[field];
0017     if ( index >= 0 && index < fields.size() ) {
0018         return fields[index];
0019     }
0020 
0021     return defaultValue;
0022 }
0023 
0024 // The default values are suitable for older versions of gosmore (the one shipped with Ubuntu Lucid Lynx)
0025 WaypointParser::WaypointParser() : m_lineSeparator(QStringLiteral("\n")), m_fieldSeparator(QLatin1Char(','))
0026 {
0027     setFieldIndex( Latitude, 0 );
0028     setFieldIndex( Longitude, 1 );
0029     setFieldIndex( JunctionType, 2 );
0030     setFieldIndex( RoadName, 4 );
0031 }
0032 
0033 void WaypointParser::setFieldIndex( Field field, int index )
0034 {
0035     m_fieldIndices[field] = index;
0036 }
0037 
0038 void WaypointParser::setLineSeparator( const QString &separator )
0039 {
0040     m_lineSeparator = separator;
0041 }
0042 
0043 void WaypointParser::setFieldSeparator( const QChar &separator )
0044 {
0045     m_fieldSeparator = separator;
0046 }
0047 
0048 void WaypointParser::addJunctionTypeMapping( const QString &key, RoutingWaypoint::JunctionType value )
0049 {
0050     m_junctionTypeMapping[key] = value;
0051 }
0052 
0053 RoutingWaypoints WaypointParser::parse( QTextStream &stream ) const
0054 {
0055     RoutingWaypoints result;
0056     QString input = stream.readAll();
0057     QStringList lines = input.split( m_lineSeparator );
0058     for( const QString &line: lines ) {
0059         if ( !line.trimmed().isEmpty() &&
0060              !line.trimmed().startsWith(QLatin1Char('#')) &&
0061              !line.startsWith( QLatin1String( "Content-Type: text/plain" ) ) ) {
0062             QStringList entries = line.split( m_fieldSeparator );
0063             if ( entries.size() >= 1 + m_fieldIndices[RoadName] ) {
0064                 qreal lon = readField<qreal>( Longitude, entries );
0065                 qreal lat = readField<qreal>( Latitude, entries );
0066                 RoutingPoint point( lon, lat );
0067                 QString junctionTypeRaw = readField<QString>( JunctionType, entries, QString() );
0068                 RoutingWaypoint::JunctionType junctionType = RoutingWaypoint::Other;
0069                 if ( m_junctionTypeMapping.contains( junctionTypeRaw ) ) {
0070                   junctionType = m_junctionTypeMapping[junctionTypeRaw];
0071                 }
0072                 QString roadType = readField<QString>( RoadType, entries, QString() );
0073                 int secondsRemaining = readField<int>( TotalSecondsRemaining, entries, -1 );
0074                 QString roadName = readField<QString>( RoadName, entries, QString() );
0075 
0076                 // Road names may contain the field separator
0077                 for (int i = 2 + m_fieldIndices[RoadName]; i<entries.size(); ++i)
0078                 {
0079                   roadName += m_fieldSeparator + entries.at(i);
0080                 }
0081 
0082                 RoutingWaypoint item( point, junctionType, junctionTypeRaw, roadType, secondsRemaining, roadName );
0083                 result.push_back( item );
0084             } else {
0085                 qDebug() << "Cannot parse " << line << "(detected " << entries.size() << " fields)";
0086             }
0087         }
0088     }
0089 
0090     return result;
0091 }
0092 
0093 } // namespace Marble