Marble

ReverseGeocodingRunnerManager.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2008 Henry de Valence <[email protected]>
4 // SPDX-FileCopyrightText: 2010 Dennis Nienhüser <[email protected]>
5 // SPDX-FileCopyrightText: 2010-2013 Bernhard Beschow <[email protected]>
6 // SPDX-FileCopyrightText: 2011 Thibaut Gridel <[email protected]>
7 
8 #include "ReverseGeocodingRunnerManager.h"
9 
10 #include "MarbleDebug.h"
11 #include "MarbleModel.h"
12 #include "GeoDataCoordinates.h"
13 #include "GeoDataPlacemark.h"
14 #include "Planet.h"
15 #include "PluginManager.h"
16 #include "ReverseGeocodingRunnerPlugin.h"
17 #include "RunnerTask.h"
18 
19 #include <QList>
20 #include <QThreadPool>
21 #include <QTimer>
22 
23 namespace Marble
24 {
25 
26 class MarbleModel;
27 
28 class Q_DECL_HIDDEN ReverseGeocodingRunnerManager::Private
29 {
30 public:
31  Private( ReverseGeocodingRunnerManager *parent, const MarbleModel *marbleModel );
32 
34 
35  void addReverseGeocodingResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark );
36  void cleanupReverseGeocodingTask( ReverseGeocodingTask *task );
37 
38  ReverseGeocodingRunnerManager *const q;
39  const MarbleModel *const m_marbleModel;
40  const PluginManager* m_pluginManager;
41  QList<ReverseGeocodingTask*> m_reverseTasks;
42  QVector<GeoDataCoordinates> m_reverseGeocodingResults;
43  QString m_reverseGeocodingResult;
44 };
45 
46 ReverseGeocodingRunnerManager::Private::Private( ReverseGeocodingRunnerManager *parent, const MarbleModel *marbleModel ) :
47  q( parent ),
48  m_marbleModel( marbleModel ),
49  m_pluginManager( marbleModel->pluginManager() )
50 {
51  qRegisterMetaType<GeoDataPlacemark>( "GeoDataPlacemark" );
52  qRegisterMetaType<GeoDataCoordinates>( "GeoDataCoordinates" );
53 }
54 
55 QList<const ReverseGeocodingRunnerPlugin *> ReverseGeocodingRunnerManager::Private::plugins( const QList<const ReverseGeocodingRunnerPlugin *> &plugins ) const
56 {
58 
59  for( const ReverseGeocodingRunnerPlugin *plugin: plugins ) {
60  if ( ( m_marbleModel && m_marbleModel->workOffline() && !plugin->canWorkOffline() ) ) {
61  continue;
62  }
63 
64  if ( !plugin->canWork() ) {
65  continue;
66  }
67 
68  if ( m_marbleModel && !plugin->supportsCelestialBody( m_marbleModel->planet()->id() ) )
69  {
70  continue;
71  }
72 
73  result << plugin;
74  }
75 
76  return result;
77 }
78 
79 void ReverseGeocodingRunnerManager::Private::addReverseGeocodingResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark )
80 {
81  if ( !m_reverseGeocodingResults.contains( coordinates ) && !placemark.address().isEmpty() ) {
82  m_reverseGeocodingResults.push_back( coordinates );
83  m_reverseGeocodingResult = placemark.address();
84  emit q->reverseGeocodingFinished( coordinates, placemark );
85  }
86 
87  if ( m_reverseTasks.isEmpty() ) {
88  emit q->reverseGeocodingFinished();
89  }
90 }
91 
92 void ReverseGeocodingRunnerManager::Private::cleanupReverseGeocodingTask( ReverseGeocodingTask *task )
93 {
94  m_reverseTasks.removeAll( task );
95  mDebug() << "removing task " << m_reverseTasks.size() << " " << (quintptr)task;
96  if ( m_reverseTasks.isEmpty() ) {
97  emit q->reverseGeocodingFinished();
98  }
99 }
100 
101 ReverseGeocodingRunnerManager::ReverseGeocodingRunnerManager( const MarbleModel *marbleModel, QObject *parent ) :
102  QObject( parent ),
103  d( new Private( this, marbleModel ) )
104 {
105  if ( QThreadPool::globalInstance()->maxThreadCount() < 4 ) {
107  }
108 }
109 
110 ReverseGeocodingRunnerManager::~ReverseGeocodingRunnerManager()
111 {
112  delete d;
113 }
114 
115 void ReverseGeocodingRunnerManager::reverseGeocoding( const GeoDataCoordinates &coordinates )
116 {
117  d->m_reverseTasks.clear();
118  d->m_reverseGeocodingResult.clear();
119  d->m_reverseGeocodingResults.removeAll( coordinates );
120 
121  QList<const ReverseGeocodingRunnerPlugin*> plugins = d->plugins( d->m_pluginManager->reverseGeocodingRunnerPlugins() );
122  for( const ReverseGeocodingRunnerPlugin* plugin: plugins ) {
123  ReverseGeocodingTask* task = new ReverseGeocodingTask( plugin->newRunner(), this, d->m_marbleModel, coordinates );
124  connect( task, SIGNAL(finished(ReverseGeocodingTask*)), this, SLOT(cleanupReverseGeocodingTask(ReverseGeocodingTask*)) );
125  mDebug() << "reverse task " << plugin->nameId() << " " << (quintptr)task;
126  d->m_reverseTasks << task;
127  }
128 
129  for( ReverseGeocodingTask* task: d->m_reverseTasks ) {
131  }
132 
133  if ( plugins.isEmpty() ) {
134  GeoDataPlacemark anonymous;
135  anonymous.setCoordinate( coordinates );
136  emit reverseGeocodingFinished( coordinates, anonymous );
137  d->cleanupReverseGeocodingTask( nullptr );
138  }
139 }
140 
141 QString ReverseGeocodingRunnerManager::searchReverseGeocoding( const GeoDataCoordinates &coordinates, int timeout ) {
142  QEventLoop localEventLoop;
143  QTimer watchdog;
144  watchdog.setSingleShot(true);
145  connect( &watchdog, SIGNAL(timeout()),
146  &localEventLoop, SLOT(quit()));
147  connect(this, SIGNAL(reverseGeocodingFinished()),
148  &localEventLoop, SLOT(quit()), Qt::QueuedConnection );
149 
150  watchdog.start( timeout );
151  reverseGeocoding( coordinates );
152  localEventLoop.exec();
153  return d->m_reverseGeocodingResult;
154 }
155 
156 }
157 
158 #include "moc_ReverseGeocodingRunnerManager.cpp"
void start(QRunnable *runnable, int priority)
void setSingleShot(bool singleShot)
QThreadPool * globalInstance()
void push_back(const T &value)
int exec(QEventLoop::ProcessEventsFlags flags)
void start(int msec)
QueuedConnection
Binds a QML item to a specific geodetic location in screen coordinates.
const QList< QKeySequence > & quit()
void setMaxThreadCount(int maxThreadCount)
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Sep 25 2023 03:50:20 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.