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

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2009 Eckhart Wörner <ewoerner@kde.org>
0004 //
0005 
0006 #include "GpsdPositionProviderPlugin.h"
0007 
0008 #include "GpsdThread.h"
0009 #include "MarbleDebug.h"
0010 
0011 #include <QIcon>
0012 
0013 #include <cmath>
0014 
0015 using namespace Marble;
0016 /* TRANSLATOR Marble::GpsdPositionProviderPlugin */
0017 
0018 QString GpsdPositionProviderPlugin::name() const
0019 {
0020     return tr( "Gpsd position provider Plugin" );
0021 }
0022 
0023 QString GpsdPositionProviderPlugin::nameId() const
0024 {
0025     return QStringLiteral("Gpsd");
0026 }
0027 
0028 QString GpsdPositionProviderPlugin::guiString() const
0029 {
0030     return tr( "gpsd" );
0031 }
0032 
0033 QString GpsdPositionProviderPlugin::version() const
0034 {
0035     return QStringLiteral("1.0");
0036 }
0037 
0038 QString GpsdPositionProviderPlugin::description() const
0039 {
0040     return tr( "Reports the position of a GPS device." );
0041 }
0042 
0043 QString GpsdPositionProviderPlugin::copyrightYears() const
0044 {
0045     return QStringLiteral("2009");
0046 }
0047 
0048 QVector<PluginAuthor> GpsdPositionProviderPlugin::pluginAuthors() const
0049 {
0050     return QVector<PluginAuthor>()
0051             << PluginAuthor(QStringLiteral("Eckhart Wörner"), QStringLiteral("ewoerner@kde.org"));
0052 
0053 }
0054 
0055 QIcon GpsdPositionProviderPlugin::icon() const
0056 {
0057     return QIcon();
0058 }
0059 
0060 void GpsdPositionProviderPlugin::initialize()
0061 {
0062     m_status = PositionProviderStatusAcquiring;
0063     emit statusChanged( m_status );
0064 
0065     m_thread = new GpsdThread;
0066     connect( m_thread, SIGNAL(gpsdInfo(gps_data_t)),
0067              this, SLOT(update(gps_data_t)) );
0068     connect( m_thread, SIGNAL(statusChanged(PositionProviderStatus)),
0069              this, SIGNAL(statusChanged(PositionProviderStatus)) );
0070     m_thread->start();
0071 }
0072 
0073 void GpsdPositionProviderPlugin::update( gps_data_t data )
0074 {
0075     PositionProviderStatus oldStatus = m_status;
0076     GeoDataCoordinates oldPosition = m_position;
0077 
0078 #if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 10 )
0079     if ( data.fix.mode <= MODE_NO_FIX || std::isnan( data.fix.longitude ) || std::isnan( data.fix.latitude ) )
0080 #else
0081     if ( data.status == STATUS_NO_FIX || std::isnan( data.fix.longitude ) || std::isnan( data.fix.latitude ) )
0082 #endif
0083         m_status = PositionProviderStatusAcquiring;
0084     else {
0085         m_status = PositionProviderStatusAvailable;
0086         m_position.set( data.fix.longitude, data.fix.latitude,
0087                         data.fix.altitude, GeoDataCoordinates::Degree );
0088         if (data.fix.mode == MODE_2D) {
0089             m_position.setAltitude(0);
0090         }
0091 
0092         m_accuracy.level = GeoDataAccuracy::Detailed;
0093 #if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 3 )
0094         if ( !std::isnan( data.fix.epx ) && !std::isnan( data.fix.epy ) ) {
0095             m_accuracy.horizontal = qMax( data.fix.epx, data.fix.epy );
0096         }
0097 #else
0098         if ( !std::isnan( data.fix.eph ) ) {
0099             m_accuracy.horizontal = data.fix.eph;
0100         }
0101 #endif
0102         if ( !std::isnan( data.fix.epv ) ) {
0103             m_accuracy.vertical = data.fix.epv;
0104         }
0105 
0106         if( !std::isnan(data.fix.speed ) )
0107         {
0108             m_speed = data.fix.speed;
0109         }
0110 
0111         if( !std::isnan( data.fix.track ) )
0112         {
0113             m_track = data.fix.track;
0114         }
0115 
0116 #if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 9 )
0117         if ( !std::isnan( data.fix.time.tv_sec ) )
0118 #else
0119         if ( !std::isnan( data.fix.time ) )
0120 #endif
0121         {
0122 #if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 9 )
0123             m_timestamp = QDateTime::fromMSecsSinceEpoch( data.fix.time.tv_sec * 1000 + data.fix.time.tv_nsec / 1000000 );
0124 #else
0125             m_timestamp = QDateTime::fromMSecsSinceEpoch( data.fix.time * 1000 );
0126 #endif
0127         }
0128     }
0129     if (m_status != oldStatus)
0130         emit statusChanged( m_status );
0131     if (!(oldPosition == m_position)) {
0132         emit positionChanged( m_position, m_accuracy );
0133     }
0134 }
0135 
0136 bool GpsdPositionProviderPlugin::isInitialized() const
0137 {
0138     return m_thread;
0139 }
0140 
0141 PositionProviderPlugin* GpsdPositionProviderPlugin::newInstance() const
0142 {
0143     return new GpsdPositionProviderPlugin;
0144 }
0145 
0146 PositionProviderStatus GpsdPositionProviderPlugin::status() const
0147 {
0148     return m_status;
0149 }
0150 
0151 GeoDataCoordinates GpsdPositionProviderPlugin::position() const
0152 {
0153     return m_position;
0154 }
0155 
0156 GeoDataAccuracy GpsdPositionProviderPlugin::accuracy() const
0157 {
0158     return m_accuracy;
0159 }
0160 
0161 GpsdPositionProviderPlugin::GpsdPositionProviderPlugin() : m_thread( nullptr ),
0162     m_speed( 0.0 ),
0163     m_track( 0.0 )
0164 {
0165 }
0166 
0167 GpsdPositionProviderPlugin::~GpsdPositionProviderPlugin()
0168 {
0169     if ( m_thread ) {
0170         m_thread->exit();
0171         
0172         if ( !m_thread->wait( 5000 ) ) {
0173             mDebug() << "Failed to stop GpsdThread";
0174         }
0175         else {
0176             delete m_thread;
0177         }
0178     }
0179 }
0180 
0181 qreal GpsdPositionProviderPlugin::speed() const
0182 {
0183     return m_speed;
0184 }
0185 
0186 qreal GpsdPositionProviderPlugin::direction() const
0187 {
0188     return m_track;
0189 }
0190 
0191 QDateTime GpsdPositionProviderPlugin::timestamp() const
0192 {
0193     return m_timestamp;
0194 }
0195 
0196 
0197 QString GpsdPositionProviderPlugin::error() const
0198 {
0199     return m_thread->error();
0200 }
0201 
0202 #include "moc_GpsdPositionProviderPlugin.cpp"