Marble

ReverseGeocodingRunnerManager.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2008 Henry de Valence <hdevalence@gmail.com>
4// SPDX-FileCopyrightText: 2010 Dennis Nienhüser <nienhueser@kde.org>
5// SPDX-FileCopyrightText: 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
6// SPDX-FileCopyrightText: 2011 Thibaut Gridel <tgridel@free.fr>
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
23namespace Marble
24{
25
26class MarbleModel;
27
28class Q_DECL_HIDDEN ReverseGeocodingRunnerManager::Private
29{
30public:
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
46ReverseGeocodingRunnerManager::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
55QList<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
79void 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
92void 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
101ReverseGeocodingRunnerManager::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
110ReverseGeocodingRunnerManager::~ReverseGeocodingRunnerManager()
111{
112 delete d;
113}
114
115void 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
141QString 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"
This file contains the headers for MarbleModel.
const QList< QKeySequence > & quit()
Binds a QML item to a specific geodetic location in screen coordinates.
int exec(ProcessEventsFlags flags)
bool isEmpty() const const
void push_back(parameter_type value)
QueuedConnection
QTaskBuilder< Task > task(Task &&task)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QThreadPool * globalInstance()
void setMaxThreadCount(int maxThreadCount)
void start(Callable &&callableToRun, int priority)
void setSingleShot(bool singleShot)
void start()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:17 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.