File indexing completed on 2024-05-05 03:50:36

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2011 Daniel Marth <danielmarth@gmx.at>
0004 // SPDX-FileCopyrightText: 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
0005 //
0006 
0007 #include "QtPositioningPositionProviderPlugin.h"
0008 
0009 #include "GeoDataAccuracy.h"
0010 #include "GeoDataCoordinates.h"
0011 
0012 #include <QGeoPositionInfoSource>
0013 #include <QGeoCoordinate>
0014 #include <QTimer>
0015 #include <QIcon>
0016 
0017 namespace Marble {
0018 
0019 class QtPositioningPositionProviderPluginPrivate
0020 {
0021 public:
0022     QtPositioningPositionProviderPluginPrivate();
0023     ~QtPositioningPositionProviderPluginPrivate();
0024 
0025     QGeoPositionInfoSource* m_source;
0026     PositionProviderStatus m_status;
0027     QTimer * m_updateChecker;
0028 
0029     QGeoPositionInfo m_lastKnownPosition;
0030 };
0031 
0032 QtPositioningPositionProviderPluginPrivate::QtPositioningPositionProviderPluginPrivate() :
0033     m_source( nullptr ),
0034     m_status( PositionProviderStatusUnavailable ),
0035     m_updateChecker( new QTimer )
0036 {
0037 }
0038 
0039 QtPositioningPositionProviderPluginPrivate::~QtPositioningPositionProviderPluginPrivate()
0040 {
0041     delete m_source;
0042 }
0043 
0044 QString QtPositioningPositionProviderPlugin::name() const
0045 {
0046     return tr( "Qt Positioning Position Provider Plugin" );
0047 }
0048 
0049 QString QtPositioningPositionProviderPlugin::nameId() const
0050 {
0051     return QStringLiteral("QtPositioning");
0052 }
0053 
0054 QString QtPositioningPositionProviderPlugin::guiString() const
0055 {
0056     return tr( "Qt Positioning Location" );
0057 }
0058 
0059 QString QtPositioningPositionProviderPlugin::version() const
0060 {
0061     return QStringLiteral("1.0");
0062 }
0063 
0064 QString QtPositioningPositionProviderPlugin::description() const
0065 {
0066     return tr( "Reports the GPS position of a QtPositioning compatible device." );
0067 }
0068 
0069 QString QtPositioningPositionProviderPlugin::copyrightYears() const
0070 {
0071     return QStringLiteral("2011-2016");
0072 }
0073 
0074 QVector<PluginAuthor> QtPositioningPositionProviderPlugin::pluginAuthors() const
0075 {
0076     return QVector<PluginAuthor>()
0077             << PluginAuthor(QStringLiteral("Daniel Marth"), QStringLiteral("danielmarth@gmx.at"));
0078 }
0079 
0080 QIcon QtPositioningPositionProviderPlugin::icon() const
0081 {
0082     return QIcon();
0083 }
0084 
0085 PositionProviderPlugin* QtPositioningPositionProviderPlugin::newInstance() const
0086 {
0087     return new QtPositioningPositionProviderPlugin;
0088 }
0089 
0090 PositionProviderStatus QtPositioningPositionProviderPlugin::status() const
0091 {
0092     return d->m_status;
0093 }
0094 
0095 GeoDataCoordinates QtPositioningPositionProviderPlugin::position() const
0096 {
0097     if ( d->m_source == nullptr ) {
0098         return GeoDataCoordinates();
0099     }
0100 
0101     const QGeoCoordinate p = d->m_lastKnownPosition.coordinate();
0102     if( !p.isValid() ) {
0103         return GeoDataCoordinates();
0104     }
0105 
0106     return GeoDataCoordinates( p.longitude(), p.latitude(),
0107                                p.altitude(), GeoDataCoordinates::Degree );
0108 }
0109 
0110 GeoDataAccuracy QtPositioningPositionProviderPlugin::accuracy() const
0111 {
0112     if ( d->m_source == nullptr ) {
0113         return GeoDataAccuracy();
0114     }
0115 
0116     const QGeoPositionInfo info = d->m_lastKnownPosition;
0117     const qreal horizontal = info.attribute( QGeoPositionInfo::HorizontalAccuracy );
0118     const qreal vertical = info.attribute( QGeoPositionInfo::VerticalAccuracy );
0119     GeoDataAccuracy::Level const level = horizontal > 0 ? GeoDataAccuracy::Detailed : GeoDataAccuracy::none;
0120     return GeoDataAccuracy( level, horizontal, vertical );
0121 }
0122 
0123 QtPositioningPositionProviderPlugin::QtPositioningPositionProviderPlugin() :
0124         d( new QtPositioningPositionProviderPluginPrivate )
0125 {
0126 }
0127 
0128 QtPositioningPositionProviderPlugin::~QtPositioningPositionProviderPlugin()
0129 {
0130     delete d->m_updateChecker;
0131     delete d;
0132 }
0133 
0134 void QtPositioningPositionProviderPlugin::initialize()
0135 {
0136     d->m_source = QGeoPositionInfoSource::createDefaultSource( this );
0137     if( d->m_source ) {
0138         d->m_status = PositionProviderStatusAcquiring;
0139         emit statusChanged(d->m_status);
0140         connect( d->m_updateChecker, SIGNAL(timeout()), this, SLOT(update()) );
0141         connect( d->m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(update(QGeoPositionInfo)) );
0142         d->m_source->setUpdateInterval( 1000 );
0143         d->m_source->startUpdates();
0144         d->m_updateChecker->start( 5000 );
0145     }
0146 }
0147 
0148 bool QtPositioningPositionProviderPlugin::isInitialized() const
0149 {
0150     return d->m_source != nullptr;
0151 }
0152 
0153 qreal QtPositioningPositionProviderPlugin::speed() const
0154 {
0155     if ( d->m_source == nullptr ) {
0156         return 0.0;
0157     }
0158 
0159     if( !d->m_lastKnownPosition.hasAttribute( QGeoPositionInfo::GroundSpeed ) ) {
0160         return 0.0;
0161     }
0162 
0163     return d->m_lastKnownPosition.attribute( QGeoPositionInfo::GroundSpeed );
0164 }
0165 
0166 qreal QtPositioningPositionProviderPlugin::direction() const
0167 {
0168     if ( d->m_source == nullptr ) {
0169         return 0.0;
0170     }
0171 
0172     if( !d->m_lastKnownPosition.hasAttribute( QGeoPositionInfo::Direction ) ) {
0173         return 0.0;
0174     }
0175 
0176     return d->m_lastKnownPosition.attribute( QGeoPositionInfo::Direction );
0177 }
0178 
0179 QDateTime QtPositioningPositionProviderPlugin::timestamp() const
0180 {
0181     if ( d->m_source == nullptr ) {
0182         return QDateTime();
0183     }
0184 
0185     return d->m_lastKnownPosition.timestamp();
0186 }
0187 
0188 void QtPositioningPositionProviderPlugin::update()
0189 {
0190     if ( d->m_source ) {
0191         update(d->m_source->lastKnownPosition());
0192     }
0193 }
0194 
0195 void QtPositioningPositionProviderPlugin::update(const QGeoPositionInfo& geoPositionInfo)
0196 {
0197     PositionProviderStatus newStatus = geoPositionInfo.isValid() ?
0198                 PositionProviderStatusAvailable :
0199                 PositionProviderStatusError;
0200     if (geoPositionInfo.isValid()) {
0201         d->m_lastKnownPosition = geoPositionInfo;
0202     }
0203 
0204     if (newStatus != d->m_status) {
0205         d->m_status = newStatus;
0206         emit statusChanged(d->m_status);
0207     }
0208 
0209     if (newStatus == PositionProviderStatusAvailable) {
0210         emit positionChanged(position(), accuracy());
0211     }
0212 }
0213 
0214 } // namespace Marble
0215 
0216 #include "moc_QtPositioningPositionProviderPlugin.cpp"