24 #include <QTemporaryFile>
34 class RoutinoRunnerPrivate
39 WaypointParser m_parser;
41 QByteArray retrieveWaypoints(
const QStringList ¶ms )
const;
43 GeoDataDocument* createDocument( GeoDataLineString* routeWaypoints,
const QVector<GeoDataPlacemark*> instructions )
const;
45 GeoDataLineString* parseRoutinoOutput(
const QByteArray &content )
const;
47 QVector<GeoDataPlacemark*> parseRoutinoInstructions(
const QByteArray &content )
const;
49 RoutinoRunnerPrivate();
52 RoutinoRunnerPrivate::RoutinoRunnerPrivate()
54 m_parser.setLineSeparator(
"\n");
55 m_parser.setFieldSeparator(
'\t');
64 f.setAutoRemove(
false );
66 m_dirName = f.fileName();
69 QFileInfo( m_dirName ).dir().mkdir( m_dirName );
73 QDir dir( m_dirName );
74 QFileInfoList entries = dir.entryInfoList( QDir::Files );
75 foreach (
const QFileInfo &file, entries ) {
76 QFile( file.absoluteFilePath() ).
remove();
78 dir.rmdir( dir.absolutePath() );
81 QString dirName()
const
89 QByteArray RoutinoRunnerPrivate::retrieveWaypoints(
const QStringList ¶ms )
const
92 QProcess routinoProcess;
93 routinoProcess.setWorkingDirectory( dir.dirName() );
95 QStringList routinoParams;
96 routinoParams << params;
97 routinoParams <<
"--dir=" + m_mapDir.absolutePath();
98 routinoParams <<
"--output-text-all";
100 routinoProcess.start(
"routino-router", routinoParams );
101 if ( !routinoProcess.waitForStarted( 5000 ) ) {
102 mDebug() <<
"Couldn't start routino-router from the current PATH. Install it to retrieve routing results from routino.";
106 if ( routinoProcess.waitForFinished(60 * 1000) ) {
107 mDebug() << routinoProcess.readAll();
108 mDebug() <<
"routino finished";
109 QFile file( routinoProcess.workingDirectory() +
"/shortest-all.txt" );
110 if ( !file.exists() ) {
111 file.setFileName( routinoProcess.workingDirectory() +
"/quickest-all.txt" );
113 if ( !file.exists() ) {
114 mDebug() <<
"Can't get results";
116 file.open( QIODevice::ReadOnly );
117 return file.readAll();
121 mDebug() <<
"Couldn't stop routino";
126 GeoDataLineString* RoutinoRunnerPrivate::parseRoutinoOutput(
const QByteArray &content )
const
128 GeoDataLineString* routeWaypoints =
new GeoDataLineString;
130 QStringList lines = QString::fromUtf8( content ).split(
'\n' );
131 mDebug() << lines.count() <<
"lines";
132 foreach(
const QString &line, lines ) {
133 if ( line.left(1) == QString(
'#') ) {
137 QStringList fields = line.split(
'\t');
138 if ( fields.size() >= 10 ) {
139 qreal lon = fields.at(1).trimmed().toDouble();
140 qreal lat = fields.at(0).trimmed().toDouble();
142 routeWaypoints->append( coordinates );
146 return routeWaypoints;
149 QVector<GeoDataPlacemark*> RoutinoRunnerPrivate::parseRoutinoInstructions(
const QByteArray &content )
const
151 QVector<GeoDataPlacemark*> result;
152 QTextStream stream( content );
153 stream.setCodec(
"UTF8");
154 stream.setAutoDetectUnicode(
true );
157 for(
int i=0; i<directions.size(); ++i ) {
158 GeoDataPlacemark* placemark =
new GeoDataPlacemark( directions[i].instructionText() );
159 GeoDataExtendedData extendedData;
160 GeoDataData turnType;
161 turnType.setName(
"turnType" );
162 turnType.setValue( qVariantFromValue<int>(
int( directions[i].turnType() ) ) );
163 extendedData.addValue( turnType );
164 GeoDataData roadName;
165 roadName.setName(
"roadName" );
166 roadName.setValue( directions[i].roadName() );
167 extendedData.addValue( roadName );
168 placemark->setExtendedData( extendedData );
169 Q_ASSERT( !directions[i].points().isEmpty() );
170 GeoDataLineString* geometry =
new GeoDataLineString;
171 QVector<RoutingWaypoint> items = directions[i].points();
172 for (
int j=0; j<items.size(); ++j ) {
173 RoutingPoint point = items[j].point();
175 geometry->append( coordinates );
177 placemark->setGeometry( geometry );
178 result.push_back( placemark );
184 GeoDataDocument* RoutinoRunnerPrivate::createDocument( GeoDataLineString* routeWaypoints,
const QVector<GeoDataPlacemark*> instructions )
const
186 if ( !routeWaypoints || routeWaypoints->isEmpty() ) {
190 GeoDataDocument* result =
new GeoDataDocument();
191 GeoDataPlacemark* routePlacemark =
new GeoDataPlacemark;
192 routePlacemark->setName(
"Route" );
193 routePlacemark->setGeometry( routeWaypoints );
194 result->append( routePlacemark );
196 QString name =
"%1 %2 (Routino)";
197 QString unit = QLatin1String(
"m" );
199 if (length >= 1000) {
203 result->setName( name.arg( length, 0,
'f', 1 ).arg( unit ) );
205 foreach( GeoDataPlacemark* placemark, instructions )
207 result->append( placemark );
215 d( new RoutinoRunnerPrivate )
230 if ( ! QFileInfo( d->m_mapDir,
"nodes.mem" ).exists() )
237 for(
int i=0; i<route->
size(); ++i )
241 params << QString(
"--lat%1=%2").arg(i+1).arg(fLat, 0,
'f', 8);
242 params << QString(
"--lon%1=%2").arg(i+1).arg(fLon, 0,
'f', 8);
246 QString transport = settings[
"transport"].toString();
247 params << QString(
"--transport=%0" ).arg( transport );
249 if ( settings[
"method"] ==
"shortest" ) {
250 params <<
"--shortest";
252 params <<
"--quickest";
260 QByteArray output = d->retrieveWaypoints( params );
262 QVector<GeoDataPlacemark*> instructions = d->parseRoutinoInstructions( output );
264 GeoDataDocument* result = d->createDocument( wayPoints, instructions );
265 mDebug() <<
this <<
"routeCalculated";
271 #include "RoutinoRunner.moc"
int size() const
Number of points in the route.
A container for Features, Styles and in the future Schemas.
RoutinoRunner(QObject *parent=0)
This file contains the headers for MarbleModel.
virtual void retrieveRoute(const RouteRequest *request)
Start a route download orw calculation.
static QString localPath()
QVector< RoutingInstruction > RoutingInstructions
qreal latitude(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
retrieves the latitude of the GeoDataCoordinates object use the unit parameter to switch between Radi...
Points to be included in a route.
RoutingProfile routingProfile() const
This file contains the headers for MarbleMap.
A LineString that allows to store a contiguous set of line segments.
qreal longitude(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
retrieves the longitude of the GeoDataCoordinates object use the unit parameter to switch between Rad...
const QHash< QString, QHash< QString, QVariant > > & pluginSettings() const
void routeCalculated(GeoDataDocument *route)
Route download/calculation is finished, result in the given route object.
QDebug mDebug()
a function to replace qDebug() in Marble library code
GeoDataCoordinates at(int index) const
Accessor for the n-th position.