28 class GosmoreRunnerPrivate
31 QFileInfo m_gosmoreMapFile;
33 WaypointParser m_parser;
36 static QMap<QString, QByteArray> m_partialRoutes;
38 QByteArray retrieveWaypoints(
const QString &query )
const;
40 GeoDataDocument* createDocument( GeoDataLineString* routeWaypoints,
const QVector<GeoDataPlacemark*> instructions )
const;
42 GeoDataLineString parseGosmoreOutput(
const QByteArray &content )
const;
44 void merge( GeoDataLineString* one,
const GeoDataLineString& two )
const;
46 QVector<GeoDataPlacemark*> parseGosmoreInstructions(
const QByteArray &content );
48 GosmoreRunnerPrivate();
51 GosmoreRunnerPrivate::GosmoreRunnerPrivate()
53 m_parser.setLineSeparator(
"\r");
54 m_parser.setFieldSeparator(
',');
59 QMap<QString, QByteArray> GosmoreRunnerPrivate::m_partialRoutes;
61 void GosmoreRunnerPrivate::merge( GeoDataLineString* one,
const GeoDataLineString& two )
const
65 QVector<GeoDataCoordinates>::const_iterator iter = two.constBegin();
66 for( ; iter != two.constEnd(); ++iter ) {
72 QByteArray GosmoreRunnerPrivate::retrieveWaypoints(
const QString &query )
const
74 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
75 env.insert(
"QUERY_STRING", query);
76 env.insert(
"LC_ALL",
"C");
78 gosmore.setProcessEnvironment(env);
80 gosmore.start(
"gosmore", QStringList() << m_gosmoreMapFile.absoluteFilePath() );
81 if (!gosmore.waitForStarted(5000)) {
82 mDebug() <<
"Couldn't start gosmore from the current PATH. Install it to retrieve routing results from gosmore.";
86 if ( gosmore.waitForFinished(15000) ) {
87 return gosmore.readAllStandardOutput();
90 mDebug() <<
"Couldn't stop gosmore";
96 GeoDataLineString GosmoreRunnerPrivate::parseGosmoreOutput(
const QByteArray &content )
const
98 GeoDataLineString routeWaypoints;
100 QStringList lines = QString::fromLocal8Bit( content ).split(
'\r' );
101 foreach(
const QString &line, lines ) {
102 QStringList fields = line.split(
',');
103 if (fields.size() >= 5) {
104 qreal lon = fields.at(1).toDouble();
105 qreal lat = fields.at(0).toDouble();
107 routeWaypoints.append( coordinates );
111 return routeWaypoints;
114 QVector<GeoDataPlacemark*> GosmoreRunnerPrivate::parseGosmoreInstructions(
const QByteArray &content )
117 QStringList lines = QString::fromUtf8( content ).split(
'\r' );
118 if ( lines.size() > 2 ) {
119 QStringList fields = lines.at( lines.size()-2 ).split(
',');
121 if ( fields.size() < 5 || fields.size() > 6 ) {
124 mDebug() <<
"Unexpected number of fields. This gosmore version may be unsupported.";
128 QVector<GeoDataPlacemark*> result;
129 QTextStream stream( content );
130 stream.setCodec(
"UTF8");
131 stream.setAutoDetectUnicode(
true );
134 for(
int i=0; i<directions.size(); ++i ) {
135 GeoDataPlacemark* placemark =
new GeoDataPlacemark( directions[i].instructionText() );
136 GeoDataExtendedData extendedData;
137 GeoDataData turnType;
138 turnType.setName(
"turnType" );
139 turnType.setValue( qVariantFromValue<int>(
int( directions[i].turnType() ) ) );
140 extendedData.addValue( turnType );
141 GeoDataData roadName;
142 roadName.setName(
"roadName" );
143 roadName.setValue( directions[i].roadName() );
144 extendedData.addValue( roadName );
145 placemark->setExtendedData( extendedData );
146 Q_ASSERT( !directions[i].points().isEmpty() );
147 GeoDataLineString* geometry =
new GeoDataLineString;
148 QVector<RoutingWaypoint> items = directions[i].points();
149 for (
int j=0; j<items.size(); ++j ) {
150 RoutingPoint point = items[j].point();
152 geometry->append( coordinates );
154 placemark->setGeometry( geometry );
155 result.push_back( placemark );
161 GeoDataDocument* GosmoreRunnerPrivate::createDocument( GeoDataLineString* routeWaypoints,
const QVector<GeoDataPlacemark*> instructions )
const
163 if ( !routeWaypoints || routeWaypoints->isEmpty() ) {
167 GeoDataDocument* result =
new GeoDataDocument();
168 GeoDataPlacemark* routePlacemark =
new GeoDataPlacemark;
169 routePlacemark->setName(
"Route" );
170 routePlacemark->setGeometry( routeWaypoints );
171 result->append( routePlacemark );
173 QString name =
"%1 %2 (Gosmore)";
174 QString unit = QLatin1String(
"m" );
176 if (length >= 1000) {
180 result->setName( name.arg( length, 0,
'f', 1 ).arg( unit ) );
182 foreach( GeoDataPlacemark* placemark, instructions )
184 result->append( placemark );
191 RoutingRunner( parent ),
192 d( new GosmoreRunnerPrivate )
196 d->m_gosmoreMapFile = QFileInfo ( mapDir,
"gosmore.pak" );
206 if ( !d->m_gosmoreMapFile.exists() )
213 QByteArray completeOutput;
215 for(
int i=0; i<route->
size()-1; ++i )
217 QString queryString =
"flat=%1&flon=%2&tlat=%3&tlon=%4&fastest=1&v=motorcar";
221 queryString = queryString.arg(fLat, 0,
'f', 8).arg(fLon, 0,
'f', 8);
225 queryString = queryString.arg(tLat, 0,
'f', 8).arg(tLon, 0,
'f', 8);
228 if ( d->m_partialRoutes.contains( queryString ) ) {
229 output = d->m_partialRoutes[queryString];
232 output = d->retrieveWaypoints( queryString );
236 d->merge( wayPoints, points );
237 completeOutput.append( output );
240 QVector<GeoDataPlacemark*> instructions = d->parseGosmoreInstructions( completeOutput );
242 GeoDataDocument* result = d->createDocument( wayPoints, instructions );
int size() const
Number of points in the route.
A 3d point representation.
A container for Features, Styles and in the future Schemas.
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.
virtual void retrieveRoute(const RouteRequest *request)
Start a route download orw calculation.
GosmoreRunner(QObject *parent=0)
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...
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.