File indexing completed on 2024-04-28 03:50:08

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2012 Dennis Nienhüser <nienhueser@kde.org>
0004 //
0005 
0006 #include "WlocatePositionProviderPlugin.h"
0007 
0008 #include <GeoDataCoordinates.h>
0009 #include <GeoDataAccuracy.h>
0010 
0011 #include <QFutureWatcher>
0012 #include <QtConcurrentRun>
0013 #include <QDateTime>
0014 #include <QIcon>
0015 
0016 #ifndef ENV_LINUX
0017 #define ENV_LINUX
0018 #define MARBLE_NEEDS_TO_CLEANUP_FOREIGN_WLOCATE_DEFINE
0019 #include <libwlocate.h>
0020 #endif
0021 
0022 #ifdef MARBLE_NEEDS_TO_CLEANUP_FOREIGN_WLOCATE_DEFINE
0023 #undef MARBLE_NEEDS_TO_CLEANUP_FOREIGN_WLOCATE_DEFINE
0024 #undef ENV_LINUX
0025 #endif
0026 
0027 namespace Marble {
0028 
0029 class WlocatePositionProviderPluginPrivate
0030 {
0031 public:
0032     PositionProviderStatus m_status;
0033     qreal m_speed;
0034     qreal m_direction;
0035     QDateTime m_timestamp;
0036     double m_longitude;
0037     double m_latitude;
0038     bool m_initialized;
0039     char m_quality;
0040     short m_ccode;
0041     QFutureWatcher<int>* m_futureWatcher;
0042 
0043     WlocatePositionProviderPluginPrivate();
0044 
0045     ~WlocatePositionProviderPluginPrivate();
0046 };
0047 
0048 WlocatePositionProviderPluginPrivate::WlocatePositionProviderPluginPrivate() :
0049         m_status( PositionProviderStatusAcquiring ), m_speed( 0 ), m_direction( 0 ),
0050         m_longitude( 0.0 ), m_latitude( 0.0 ), m_initialized( false ),
0051         m_quality( 0 ), m_ccode( 0 ), m_futureWatcher( nullptr )
0052 {
0053     // nothing to do
0054 }
0055 
0056 WlocatePositionProviderPluginPrivate::~WlocatePositionProviderPluginPrivate()
0057 {
0058     // nothing to do
0059 }
0060 
0061 QString WlocatePositionProviderPlugin::name() const
0062 {
0063     return tr( "Wlocate Position Provider Plugin" );
0064 }
0065 
0066 QString WlocatePositionProviderPlugin::nameId() const
0067 {
0068     return QStringLiteral("WlocatePositionProvider");
0069 }
0070 
0071 QString WlocatePositionProviderPlugin::guiString() const
0072 {
0073     return tr( "WLAN (Open WLAN Map)" );
0074 }
0075 
0076 QString WlocatePositionProviderPlugin::version() const
0077 {
0078     return QStringLiteral("1.0");
0079 }
0080 
0081 QString WlocatePositionProviderPlugin::description() const
0082 {
0083     return tr( "Reports the current position based on nearby WLAN access points" );
0084 }
0085 
0086 QString WlocatePositionProviderPlugin::copyrightYears() const
0087 {
0088     return QStringLiteral("2012");
0089 }
0090 
0091 QVector<PluginAuthor> WlocatePositionProviderPlugin::pluginAuthors() const
0092 {
0093     return QVector<PluginAuthor>()
0094             << PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org"));
0095 }
0096 
0097 QIcon WlocatePositionProviderPlugin::icon() const
0098 {
0099     return QIcon();
0100 }
0101 
0102 PositionProviderPlugin* WlocatePositionProviderPlugin::newInstance() const
0103 {
0104     return new WlocatePositionProviderPlugin;
0105 }
0106 
0107 PositionProviderStatus WlocatePositionProviderPlugin::status() const
0108 {
0109     return d->m_status;
0110 }
0111 
0112 GeoDataCoordinates WlocatePositionProviderPlugin::position() const
0113 {
0114     return GeoDataCoordinates( d->m_longitude, d->m_latitude, 0.0, GeoDataCoordinates::Degree );
0115 }
0116 
0117 qreal WlocatePositionProviderPlugin::speed() const
0118 {
0119     return d->m_speed;
0120 }
0121 
0122 qreal WlocatePositionProviderPlugin::direction() const
0123 {
0124     return d->m_direction;
0125 }
0126 
0127 GeoDataAccuracy WlocatePositionProviderPlugin::accuracy() const
0128 {
0129     GeoDataAccuracy result;
0130 
0131     if ( status() == PositionProviderStatusAvailable ) {
0132         result.level = GeoDataAccuracy::Detailed;
0133         /** @todo: Try mapping the accuracy percentage returned by libwlocate to something useful */
0134         result.horizontal = 0;
0135         result.vertical = 0;
0136     }
0137     else {
0138         result.level = GeoDataAccuracy::none;
0139         result.horizontal = 0;
0140         result.vertical = 0;
0141     }
0142 
0143     return result;
0144 }
0145 
0146 QDateTime WlocatePositionProviderPlugin::timestamp() const
0147 {
0148     return d->m_timestamp;
0149 }
0150 
0151 WlocatePositionProviderPlugin::WlocatePositionProviderPlugin() :
0152         d( new WlocatePositionProviderPluginPrivate )
0153 {
0154     // nothing to do
0155 }
0156 
0157 WlocatePositionProviderPlugin::~WlocatePositionProviderPlugin()
0158 {
0159     delete d;
0160 }
0161 
0162 void WlocatePositionProviderPlugin::initialize()
0163 {
0164     d->m_initialized = true;
0165     update();
0166 }
0167 
0168 bool WlocatePositionProviderPlugin::isInitialized() const
0169 {
0170     return d->m_initialized;
0171 }
0172 
0173 void WlocatePositionProviderPlugin::update()
0174 {
0175     if ( !d->m_futureWatcher ) {
0176         d->m_futureWatcher = new QFutureWatcher<int>( this );
0177         connect( d->m_futureWatcher, SIGNAL(finished()), this, SLOT(handleWlocateResult()) );
0178     }
0179 
0180     QFuture<int> future = QtConcurrent::run( &wloc_get_location, &d->m_latitude, &d->m_longitude, &d->m_quality, &d->m_ccode );
0181     d->m_futureWatcher->setFuture( future );
0182 }
0183 
0184 void WlocatePositionProviderPlugin::handleWlocateResult()
0185 {
0186     if ( d->m_futureWatcher->isFinished() ) {
0187         int const returnCode = d->m_futureWatcher->result();
0188         d->m_status = returnCode == WLOC_OK ? PositionProviderStatusAvailable : PositionProviderStatusError;
0189         if ( d->m_status == PositionProviderStatusAvailable ) {
0190             d->m_timestamp = QDateTime::currentDateTimeUtc();
0191             emit positionChanged( position(), accuracy() );
0192         }
0193     }
0194 }
0195 
0196 } // namespace Marble
0197 
0198 #include "moc_WlocatePositionProviderPlugin.cpp"