File indexing completed on 2024-04-14 03:47:59

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2011 Guillaume Martres <smarter@ubuntu.com>
0004 // SPDX-FileCopyrightText: 2011, 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
0005 //
0006 
0007 #include "PlacemarkPositionProviderPlugin.h"
0008 
0009 #include "GeoDataPlacemark.h"
0010 #include "MarbleClock.h"
0011 #include "MarbleModel.h"
0012 #include "MarbleDebug.h"
0013 
0014 #include <QIcon>
0015 
0016 using namespace Marble;
0017 
0018 PlacemarkPositionProviderPlugin::PlacemarkPositionProviderPlugin( MarbleModel *marbleModel, QObject* parent )
0019     : PositionProviderPlugin(parent),
0020       m_marbleModel( marbleModel ),
0021       m_placemark( nullptr ),
0022       m_speed( 0 ),
0023       m_direction( 0.0 ),
0024       m_status( PositionProviderStatusUnavailable ),
0025       m_isInitialized( false )
0026 {
0027     m_accuracy.level = GeoDataAccuracy::Detailed;
0028 }
0029 
0030 QString PlacemarkPositionProviderPlugin::name() const
0031 {
0032     return tr( "Placemark position provider Plugin" );
0033 }
0034 
0035 QString PlacemarkPositionProviderPlugin::nameId() const
0036 {
0037     return QStringLiteral("Placemark");
0038 }
0039 
0040 QString PlacemarkPositionProviderPlugin::guiString() const
0041 {
0042     return tr( "Placemark" );
0043 }
0044 
0045 QString PlacemarkPositionProviderPlugin::version() const
0046 {
0047     return QStringLiteral("1.0");
0048 }
0049 
0050 QString PlacemarkPositionProviderPlugin::description() const
0051 {
0052     return tr( "Reports the position of a placemark" );
0053 }
0054 
0055 QString PlacemarkPositionProviderPlugin::copyrightYears() const
0056 {
0057     return QStringLiteral("2011, 2012");
0058 }
0059 
0060 QVector<PluginAuthor> PlacemarkPositionProviderPlugin::pluginAuthors() const
0061 {
0062     return QVector<PluginAuthor>()
0063             << PluginAuthor(QStringLiteral("Guillaume Martres"), QStringLiteral("smarter@ubuntu.com"))
0064             << PluginAuthor(QStringLiteral("Bernhard Beschow"), QStringLiteral("bbeschow@cs.tu-berlin.de"));
0065 }
0066 
0067 QIcon PlacemarkPositionProviderPlugin::icon() const
0068 {
0069     return QIcon();
0070 }
0071 
0072 void PlacemarkPositionProviderPlugin::initialize()
0073 {
0074     if ( m_marbleModel ) {
0075         setPlacemark( m_marbleModel->trackedPlacemark() );
0076         connect( m_marbleModel, SIGNAL(trackedPlacemarkChanged(const GeoDataPlacemark*)),
0077                  this, SLOT(setPlacemark(const GeoDataPlacemark*)) );
0078     } else {
0079         mDebug() << "PlacemarkPositionProviderPlugin: MarbleModel not set, cannot track placemarks.";
0080     }
0081     m_isInitialized = true;
0082 }
0083 
0084 bool PlacemarkPositionProviderPlugin::isInitialized() const
0085 {
0086     return m_isInitialized;
0087 }
0088 
0089 PositionProviderPlugin* PlacemarkPositionProviderPlugin::newInstance() const
0090 {
0091     return new PlacemarkPositionProviderPlugin( m_marbleModel );
0092 }
0093 
0094 PositionProviderStatus PlacemarkPositionProviderPlugin::status() const
0095 {
0096     return m_status;
0097 }
0098 
0099 GeoDataCoordinates PlacemarkPositionProviderPlugin::position() const
0100 {
0101     return m_coordinates;
0102 }
0103 
0104 GeoDataAccuracy PlacemarkPositionProviderPlugin::accuracy() const
0105 {
0106     return m_accuracy;
0107 }
0108 
0109 qreal PlacemarkPositionProviderPlugin::speed() const
0110 {
0111     return m_speed;
0112 }
0113 
0114 qreal PlacemarkPositionProviderPlugin::direction() const
0115 {
0116     return m_direction;
0117 }
0118 
0119 QDateTime PlacemarkPositionProviderPlugin::timestamp() const
0120 {
0121     return m_marbleModel->clockDateTime();
0122 }
0123 
0124 void PlacemarkPositionProviderPlugin::setPlacemark( const GeoDataPlacemark *placemark )
0125 {
0126     const GeoDataPlacemark *const oldPlacemark = m_placemark;
0127 
0128     if ( oldPlacemark != nullptr ) {
0129         emit statusChanged( PositionProviderStatusUnavailable );
0130     }
0131 
0132     m_placemark   = placemark;
0133     m_timestamp   = placemark ? m_marbleModel->clockDateTime() : QDateTime();
0134     GeoDataCoordinates const newCoordinates = placemark ? placemark->coordinate( m_timestamp ) : GeoDataCoordinates();
0135     if ( m_coordinates.isValid() && newCoordinates.isValid() ) {
0136         m_direction = m_coordinates.bearing( newCoordinates, GeoDataCoordinates::Degree, GeoDataCoordinates::FinalBearing );
0137     }
0138     m_coordinates = newCoordinates;
0139     m_status      = placemark ? PositionProviderStatusAvailable : PositionProviderStatusUnavailable;
0140     m_speed       = 0.0;
0141 
0142     disconnect( m_marbleModel->clock(), SIGNAL(timeChanged()), this, SLOT(updatePosition()) );
0143     if ( placemark ) {
0144         connect( m_marbleModel->clock(), SIGNAL(timeChanged()), this, SLOT(updatePosition()) );
0145     }
0146 
0147     if ( oldPlacemark != m_placemark && m_placemark != nullptr ) {
0148         emit statusChanged( m_status );
0149     }
0150 
0151     if ( m_status == PositionProviderStatusAvailable ) {
0152         emit positionChanged( m_coordinates, m_accuracy );
0153     }
0154 }
0155 
0156 void PlacemarkPositionProviderPlugin::updatePosition()
0157 {
0158     if ( m_placemark == nullptr ) {
0159         return;
0160     }
0161 
0162     Q_ASSERT( m_marbleModel && "MarbleModel missing in PlacemarkPositionProviderPlugin" );
0163 
0164     const GeoDataCoordinates previousCoordinates = m_coordinates;
0165     m_coordinates = m_placemark->coordinate( m_marbleModel->clock()->dateTime() );
0166     m_direction = previousCoordinates.bearing( m_coordinates, GeoDataCoordinates::Degree, GeoDataCoordinates::FinalBearing );
0167 
0168     if ( m_timestamp.isValid() ) {
0169         const qreal averageAltitude = ( m_coordinates.altitude() + m_coordinates.altitude() ) / 2.0 + m_marbleModel->planetRadius();
0170         const qreal distance = previousCoordinates.sphericalDistanceTo(m_coordinates) * averageAltitude;
0171         const qreal seconds = m_timestamp.msecsTo( m_marbleModel->clockDateTime() ) / 1000.0;
0172         m_speed = ( seconds > 0 ) ? ( distance / seconds ) : 0;
0173     }
0174     else {
0175         m_speed = 0;
0176     }
0177 
0178     m_timestamp = m_marbleModel->clockDateTime();
0179 
0180     emit positionChanged( m_coordinates, m_accuracy );
0181 }
0182 
0183 #include "moc_PlacemarkPositionProviderPlugin.cpp"