• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.12
  • kdeedu
  • marble
  • src
  • plugins
  • runner
  • traveling-salesman
TravelingSalesmanRunner.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2010 Dennis Nienhüser <earthwings@gentoo.org>
9 //
10 
11 #include "TravelingSalesmanRunner.h"
12 
13 #include "MarbleDebug.h"
14 #include "MarbleDirs.h"
15 #include "routing/RouteRequest.h"
16 #include "GeoDataDocument.h"
17 #include "GeoDataParser.h"
18 
19 #include <QProcess>
20 #include <QMap>
21 #include <QTemporaryFile>
22 
23 namespace Marble
24 {
25 
26 class TravelingSalesmanRunnerPrivate
27 {
28 public:
29  QFileInfo m_travelingsalesmanJar;
30 
31  GeoDataLineString retrieveWaypoints( const QPair<QString, QString> &query ) const;
32 
33  GeoDataDocument* createDocument( GeoDataLineString* routeWaypoints ) const;
34 
35  GeoDataLineString parseTravelingSalesmanOutput( QFile &file ) const;
36 
37  void merge( GeoDataLineString* one, const GeoDataLineString& two ) const;
38 
40  static QMap<QString, GeoDataLineString> m_partialRoutes;
41 };
42 
43 QMap<QString, GeoDataLineString> TravelingSalesmanRunnerPrivate::m_partialRoutes;
44 
45 void TravelingSalesmanRunnerPrivate::merge( GeoDataLineString* one, const GeoDataLineString& two ) const
46 {
47  Q_ASSERT( one );
48 
49  QVector<GeoDataCoordinates>::const_iterator iter = two.constBegin();
50  for ( ; iter != two.constEnd(); ++iter ) {
52  one->append( *iter );
53  }
54 }
55 
56 GeoDataLineString TravelingSalesmanRunnerPrivate::retrieveWaypoints( const QPair<QString, QString> &query ) const
57 {
58  QString cacheItem = query.first + query.second;
59  if ( m_partialRoutes.contains( cacheItem ) ) {
60  return m_partialRoutes[cacheItem];
61  }
62 
63  QTemporaryFile gpxFile;
64  if ( !gpxFile.open() ) {
65  mDebug() << "Unable to create a temporary work file";
66  return GeoDataLineString();
67  }
68 
69  QProcess travelingsalesman;
70  QStringList arguments = QStringList() << "-jar" << m_travelingsalesmanJar.absoluteFilePath();
71  arguments << "route" << "-gpx" << gpxFile.fileName();
72  arguments << query.first << query.second;
73  travelingsalesman.start( "java", arguments );
74  if ( !travelingsalesman.waitForStarted( 5000 ) ) {
75  mDebug() << "Couldn't start travelingsalesman from the current PATH. Is java setup correctly?";
76  return GeoDataLineString();
77  }
78 
79  if ( travelingsalesman.waitForFinished( 60 * 1000 ) ) {
80  m_partialRoutes[cacheItem] = parseTravelingSalesmanOutput( gpxFile );
81  return m_partialRoutes[cacheItem];
82  } else {
83  mDebug() << "Couldn't stop travelingsalesman";
84  }
85 
86  return GeoDataLineString();
87 }
88 
89 GeoDataLineString TravelingSalesmanRunnerPrivate::parseTravelingSalesmanOutput( QFile &file ) const
90 {
91  GeoDataParser parser( GeoData_GPX );
92  if ( !parser.read( &file ) ) {
93  mDebug() << "Could not parse gpx file " << file.fileName();
94  return GeoDataLineString();
95  }
96 
97  GeoDataLineString result;
98  GeoDocument* document = parser.releaseDocument();
99  GeoDataDocument* route = dynamic_cast<GeoDataDocument*>( document );
100 
101  if ( route ) {
102  if ( route->placemarkList().size() == 1 ) {
103  GeoDataPlacemark* placemark = route->placemarkList().first();
104  GeoDataMultiGeometry* multi = dynamic_cast<GeoDataMultiGeometry*>( placemark->geometry() );
105  if ( multi && multi->size() == 1 ) {
106  GeoDataLineString* lineString = dynamic_cast<GeoDataLineString*>( &multi->first() );
107  if ( lineString ) {
108  return *lineString;
109  }
110  }
111  }
112  }
113  delete document;
114  return result;
115 }
116 
117 GeoDataDocument* TravelingSalesmanRunnerPrivate::createDocument( GeoDataLineString* routeWaypoints ) const
118 {
119  if ( !routeWaypoints || routeWaypoints->isEmpty() ) {
120  return 0;
121  }
122 
123  GeoDataDocument* result = new GeoDataDocument();
124  GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
125  routePlacemark->setName( "Route" );
126  routePlacemark->setGeometry( routeWaypoints );
127  result->append( routePlacemark );
128 
129  QString name = "%1 %2 (Traveling Salesman)";
130  QString unit = 'm';
131  qreal length = routeWaypoints->length( EARTH_RADIUS );
132  if ( length >= 1000 ) {
133  length /= 1000.0;
134  unit = "km";
135  }
136  result->setName( name.arg( length, 0, 'f', 1 ).arg( unit ) );
137  return result;
138 }
139 
140 TravelingSalesmanRunner::TravelingSalesmanRunner( QObject *parent ) :
141  MarbleAbstractRunner( parent ),
142  d( new TravelingSalesmanRunnerPrivate )
143 {
144  // Check installation
145  QDir mapDir( MarbleDirs::localPath() + "/maps/earth/traveling-salesman/" );
146  d->m_travelingsalesmanJar = QFileInfo ( mapDir, "traveling-salesman.jar" );
147 }
148 
149 TravelingSalesmanRunner::~TravelingSalesmanRunner()
150 {
151  delete d;
152 }
153 
154 GeoDataFeature::GeoDataVisualCategory TravelingSalesmanRunner::category() const
155 {
156  return GeoDataFeature::OsmSite;
157 }
158 
159 void TravelingSalesmanRunner::retrieveRoute( RouteRequest *route )
160 {
161  if ( !d->m_travelingsalesmanJar.exists() ) {
162  emit routeCalculated( 0 );
163  return;
164  }
165 
166  GeoDataLineString* wayPoints = new GeoDataLineString;
167 
168  for ( int i = 0; i < route->size() - 1; ++i ) {
169  QPair<QString, QString> queryString;
170  GeoDataCoordinates source = route->at( i );
171  double fLon = source.longitude( GeoDataCoordinates::Degree );
172  double fLat = source.latitude( GeoDataCoordinates::Degree );
173  queryString.first = QString( "[%1,%2]" ).arg( fLat, 0, 'f', 8 ).arg( fLon, 0, 'f', 8 );
174  GeoDataCoordinates destination = route->at( i + 1 );
175  double tLon = destination.longitude( GeoDataCoordinates::Degree );
176  double tLat = destination.latitude( GeoDataCoordinates::Degree );
177  queryString.second = QString( "[%1,%2]" ).arg( tLat, 0, 'f', 8 ).arg( tLon, 0, 'f', 8 );
178 
179  d->merge( wayPoints, d->retrieveWaypoints( queryString ) );
180  }
181 
182  GeoDataDocument* result = d->createDocument( wayPoints );
183  emit routeCalculated( result );
184 }
185 
186 } // namespace Marble
GeoDataDocument.h
Marble::RouteRequest::size
int size() const
Number of points in the route.
Definition: RouteRequest.cpp:126
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
Marble::GeoDataDocument
A container for Features, Styles and in the future Schemas.
Definition: GeoDataDocument.h:64
Marble::TravelingSalesmanRunner::TravelingSalesmanRunner
TravelingSalesmanRunner(QObject *parent=0)
Definition: TravelingSalesmanRunner.cpp:140
Marble::GeoDataFeature::OsmSite
Definition: GeoDataFeature.h:122
MarbleAbstractRunner
GeoDataParser.h
Marble::MarbleDirs::localPath
static QString localPath()
Definition: MarbleDirs.cpp:217
Marble::GeoDataCoordinates::latitude
qreal latitude(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
retrieves the latitude of the GeoDataCoordinates object use the unit parameter to switch between Radi...
Definition: GeoDataCoordinates.cpp:751
QObject
MarbleDebug.h
TravelingSalesmanRunner.h
Marble::GeoDataCoordinates::Degree
Definition: GeoDataCoordinates.h:66
Marble::RouteRequest
Points to be included in a route.
Definition: RouteRequest.h:31
Marble::EARTH_RADIUS
const qreal EARTH_RADIUS
Definition: MarbleGlobal.h:238
MarbleDirs.h
Marble::GeoDataLineString
A LineString that allows to store a contiguous set of line segments.
Definition: GeoDataLineString.h:75
Marble::GeoDataCoordinates::longitude
qreal longitude(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
retrieves the longitude of the GeoDataCoordinates object use the unit parameter to switch between Rad...
Definition: GeoDataCoordinates.cpp:739
Marble::TravelingSalesmanRunner::category
GeoDataFeature::GeoDataVisualCategory category() const
Definition: TravelingSalesmanRunner.cpp:154
Marble::TravelingSalesmanRunner::retrieveRoute
virtual void retrieveRoute(RouteRequest *request)
Definition: TravelingSalesmanRunner.cpp:159
RouteRequest.h
Marble::GeoDataFeature::GeoDataVisualCategory
GeoDataVisualCategory
A categorization of a placemark as defined by ...FIXME.
Definition: GeoDataFeature.h:75
Marble::TravelingSalesmanRunner::~TravelingSalesmanRunner
~TravelingSalesmanRunner()
Definition: TravelingSalesmanRunner.cpp:149
Marble::mDebug
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
Marble::RouteRequest::at
GeoDataCoordinates at(int index) const
Accessor for the n-th position.
Definition: RouteRequest.cpp:149
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:53 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal