File indexing completed on 2024-04-21 03:50:27
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2010 Dennis Nienhüser <nienhueser@kde.org> 0004 // SPDX-FileCopyrightText: 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de> 0005 // 0006 0007 #include "GosmoreReverseGeocodingRunner.h" 0008 0009 #include "MarbleDebug.h" 0010 #include "MarbleDirs.h" 0011 #include "routing/RouteRequest.h" 0012 #include "routing/instructions/WaypointParser.h" 0013 #include "routing/instructions/InstructionTransformation.h" 0014 #include "GeoDataExtendedData.h" 0015 #include "GeoDataData.h" 0016 #include "GeoDataPlacemark.h" 0017 0018 #include <QProcess> 0019 0020 namespace Marble 0021 { 0022 0023 class GosmoreRunnerPrivate 0024 { 0025 public: 0026 QFileInfo m_gosmoreMapFile; 0027 0028 WaypointParser m_parser; 0029 0030 QByteArray retrieveWaypoints( const QString &query ) const; 0031 0032 GosmoreRunnerPrivate(); 0033 }; 0034 0035 GosmoreRunnerPrivate::GosmoreRunnerPrivate() 0036 { 0037 m_parser.setLineSeparator("\r"); 0038 m_parser.setFieldSeparator(QLatin1Char(',')); 0039 m_parser.setFieldIndex( WaypointParser::RoadName, 4 ); 0040 m_parser.addJunctionTypeMapping( "Jr", RoutingWaypoint::Roundabout ); 0041 } 0042 0043 QByteArray GosmoreRunnerPrivate::retrieveWaypoints( const QString &query ) const 0044 { 0045 QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); 0046 env.insert("QUERY_STRING", query); 0047 env.insert("LC_ALL", "C"); 0048 QProcess gosmore; 0049 gosmore.setProcessEnvironment(env); 0050 0051 gosmore.start("gosmore", QStringList() << m_gosmoreMapFile.absoluteFilePath() ); 0052 if (!gosmore.waitForStarted(5000)) { 0053 mDebug() << "Couldn't start gosmore from the current PATH. Install it to retrieve routing results from gosmore."; 0054 return QByteArray(); 0055 } 0056 0057 if ( gosmore.waitForFinished(15000) ) { 0058 return gosmore.readAllStandardOutput(); 0059 } 0060 else { 0061 mDebug() << "Couldn't stop gosmore"; 0062 } 0063 0064 return QByteArray(); 0065 } 0066 0067 GosmoreRunner::GosmoreRunner( QObject *parent ) : 0068 ReverseGeocodingRunner( parent ), 0069 d( new GosmoreRunnerPrivate ) 0070 { 0071 // Check installation 0072 QDir mapDir(MarbleDirs::localPath() + QLatin1String("/maps/earth/gosmore/")); 0073 d->m_gosmoreMapFile = QFileInfo ( mapDir, "gosmore.pak" ); 0074 } 0075 0076 GosmoreRunner::~GosmoreRunner() 0077 { 0078 delete d; 0079 } 0080 0081 void GosmoreRunner::reverseGeocoding( const GeoDataCoordinates &coordinates ) 0082 { 0083 if ( !d->m_gosmoreMapFile.exists() ) 0084 { 0085 emit reverseGeocodingFinished( coordinates, GeoDataPlacemark() ); 0086 return; 0087 } 0088 0089 QString queryString = "flat=%1&flon=%2&tlat=%1&tlon=%2&fastest=1&v=motorcar"; 0090 double lon = coordinates.longitude( GeoDataCoordinates::Degree ); 0091 double lat = coordinates.latitude( GeoDataCoordinates::Degree ); 0092 queryString = queryString.arg( lat, 0, 'f', 8).arg(lon, 0, 'f', 8 ); 0093 QByteArray output = d->retrieveWaypoints( queryString ); 0094 0095 GeoDataPlacemark placemark; 0096 placemark.setCoordinate( coordinates ); 0097 0098 QStringList lines = QString::fromUtf8(output).split(QLatin1Char('\r')); 0099 if ( lines.size() > 2 ) { 0100 QStringList fields = lines.at( lines.size()-2 ).split(QLatin1Char(',')); 0101 if ( fields.size() >= 5 ) { 0102 QString road = fields.last().trimmed(); 0103 placemark.setAddress( road ); 0104 GeoDataExtendedData extendedData; 0105 extendedData.addValue(GeoDataData(QStringLiteral("road"), road)); 0106 placemark.setExtendedData( extendedData ); 0107 } 0108 } 0109 0110 emit reverseGeocodingFinished( coordinates, placemark ); 0111 } 0112 0113 } // namespace Marble