File indexing completed on 2024-05-05 03:49:20
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2011 Dennis Nienhüser <nienhueser@kde.org> 0004 // 0005 0006 #include "Tracking.h" 0007 0008 #include "MarbleQuickItem.h" 0009 #include "MarbleModel.h" 0010 #include "PositionTracking.h" 0011 #include "RenderPlugin.h" 0012 #include "ViewportParams.h" 0013 #include "AutoNavigation.h" 0014 0015 namespace Marble { 0016 0017 Tracking::Tracking( QObject* parent) : QObject( parent ), 0018 m_showTrack( true ), 0019 m_positionSource( nullptr ), 0020 m_positionMarker( nullptr ), 0021 m_marbleQuickItem( nullptr ), 0022 m_hasLastKnownPosition( false ), 0023 m_autoNavigation( nullptr ), 0024 m_positionMarkerType( None ) 0025 { 0026 connect( &m_lastKnownPosition, SIGNAL(longitudeChanged()), this, SLOT(setHasLastKnownPosition()) ); 0027 connect( &m_lastKnownPosition, SIGNAL(latitudeChanged()), this, SLOT(setHasLastKnownPosition()) ); 0028 } 0029 0030 bool Tracking::showTrack() const 0031 { 0032 return m_showTrack; 0033 } 0034 0035 void Tracking::setShowTrack( bool show ) 0036 { 0037 if ( show != m_showTrack ) { 0038 if ( m_marbleQuickItem ) { 0039 m_marbleQuickItem->model()->positionTracking()->setTrackVisible( show ); 0040 m_marbleQuickItem->update(); 0041 } 0042 0043 m_showTrack = show; 0044 emit showTrackChanged(); 0045 } 0046 } 0047 0048 PositionSource* Tracking::positionSource() 0049 { 0050 return m_positionSource; 0051 } 0052 0053 void Tracking::setPositionSource( PositionSource* source ) 0054 { 0055 if ( source != m_positionSource ) { 0056 m_positionSource = source; 0057 if ( source ) { 0058 connect( source, SIGNAL(positionChanged()), 0059 this, SLOT(updatePositionMarker()) ); 0060 connect( source, SIGNAL(positionChanged()), 0061 this, SLOT(updateLastKnownPosition()) ); 0062 connect( source, SIGNAL(hasPositionChanged()), 0063 this, SLOT(updatePositionMarker()) ); 0064 connect( source, SIGNAL(positionChanged()), 0065 this, SIGNAL(distanceChanged()) ); 0066 } 0067 emit positionSourceChanged(); 0068 } 0069 } 0070 0071 MarbleQuickItem* Tracking::map() 0072 { 0073 return m_marbleQuickItem; 0074 } 0075 0076 void Tracking::setMap( MarbleQuickItem* item ) 0077 { 0078 if ( item != m_marbleQuickItem ) { 0079 m_marbleQuickItem = item; 0080 0081 if ( m_marbleQuickItem ) { 0082 m_marbleQuickItem->model()->positionTracking()->setTrackVisible( showTrack() ); 0083 setShowPositionMarkerPlugin( m_positionMarkerType == Arrow ); 0084 0085 connect( m_marbleQuickItem, SIGNAL(visibleLatLonAltBoxChanged()), this, SLOT(updatePositionMarker()) ); 0086 connect( m_marbleQuickItem, SIGNAL(mapThemeChanged()), this, SLOT(updatePositionMarker()) ); 0087 } 0088 0089 emit mapChanged(); 0090 } 0091 } 0092 0093 void Tracking::setPositionMarker( QObject* marker ) 0094 { 0095 if ( marker != m_positionMarker ) { 0096 m_positionMarker = marker; 0097 emit positionMarkerChanged(); 0098 } 0099 } 0100 0101 QObject* Tracking::positionMarker() 0102 { 0103 return m_positionMarker; 0104 } 0105 0106 void Tracking::updatePositionMarker() 0107 { 0108 if ( m_marbleQuickItem && m_positionMarker && m_positionMarkerType == Circle ) { 0109 Coordinate* position = nullptr; 0110 bool visible = (m_marbleQuickItem->model()->planetId() == QLatin1String("earth")); 0111 if ( m_positionSource && m_positionSource->hasPosition() ) { 0112 position = m_positionSource->position(); 0113 } else if ( hasLastKnownPosition() ) { 0114 position = lastKnownPosition(); 0115 } else { 0116 visible = false; 0117 } 0118 0119 qreal x(0), y(0); 0120 if ( position ) { 0121 Marble::GeoDataCoordinates const pos( position->longitude(), position->latitude(), 0.0, GeoDataCoordinates::Degree ); 0122 visible = visible && m_marbleQuickItem->map()->viewport()->screenCoordinates( pos.longitude(), pos.latitude(), x, y ); 0123 QQuickItem* item = qobject_cast<QQuickItem*>( m_positionMarker ); 0124 if ( item ) { 0125 item->setVisible( visible ); 0126 if ( visible ) { 0127 item->setX( x - item->width() / 2.0 ); 0128 item->setY( y - item->height() / 2.0 ); 0129 } 0130 } 0131 } 0132 } else if ( m_positionMarkerType != Circle ) { 0133 QQuickItem* item = qobject_cast<QQuickItem*>( m_positionMarker ); 0134 if ( item ) { 0135 item->setVisible( false ); 0136 } 0137 } 0138 } 0139 0140 void Tracking::updateLastKnownPosition() 0141 { 0142 if ( m_positionSource && m_positionSource->hasPosition() ) { 0143 setLastKnownPosition( m_positionSource->position() ); 0144 } 0145 } 0146 0147 void Tracking::setHasLastKnownPosition() 0148 { 0149 if ( !m_hasLastKnownPosition ) { 0150 m_hasLastKnownPosition = true; 0151 emit hasLastKnownPositionChanged(); 0152 } 0153 } 0154 0155 void Tracking::setShowPositionMarkerPlugin( bool visible ) 0156 { 0157 if ( m_marbleQuickItem ) { 0158 QList<RenderPlugin*> const renderPlugins = m_marbleQuickItem->map()->renderPlugins(); 0159 for( RenderPlugin* renderPlugin: renderPlugins ) { 0160 Q_ASSERT( renderPlugin ); 0161 if (renderPlugin->nameId() == QLatin1String("positionMarker")) { 0162 renderPlugin->setEnabled( true ); 0163 renderPlugin->setVisible( visible ); 0164 } 0165 } 0166 } 0167 } 0168 0169 bool Tracking::hasLastKnownPosition() const 0170 { 0171 return m_hasLastKnownPosition; 0172 } 0173 0174 Coordinate * Tracking::lastKnownPosition() 0175 { 0176 return &m_lastKnownPosition; 0177 } 0178 0179 void Tracking::setLastKnownPosition( Coordinate* lastKnownPosition ) 0180 { 0181 if ( lastKnownPosition && *lastKnownPosition != m_lastKnownPosition ) { 0182 m_lastKnownPosition.setCoordinates( lastKnownPosition->coordinates() ); 0183 emit lastKnownPositionChanged(); 0184 } 0185 } 0186 0187 bool Tracking::autoCenter() const 0188 { 0189 if ( m_autoNavigation ) { 0190 return m_autoNavigation->recenterMode() != Marble::AutoNavigation::DontRecenter; 0191 } 0192 0193 return false; 0194 } 0195 0196 void Tracking::setAutoCenter( bool enabled ) 0197 { 0198 if ( autoCenter() != enabled ) { 0199 if ( enabled && !m_autoNavigation && m_marbleQuickItem ) { 0200 m_autoNavigation = new Marble::AutoNavigation( m_marbleQuickItem->model(), m_marbleQuickItem->map()->viewport(), this ); 0201 connect( m_autoNavigation, SIGNAL(zoomIn(FlyToMode)), 0202 m_marbleQuickItem, SLOT(zoomIn()) ); 0203 connect( m_autoNavigation, SIGNAL(zoomOut(FlyToMode)), 0204 m_marbleQuickItem, SLOT(zoomOut()) ); 0205 connect( m_autoNavigation, SIGNAL(centerOn(GeoDataCoordinates,bool)), 0206 m_marbleQuickItem, SLOT(centerOn(GeoDataCoordinates)) ); 0207 0208 connect( m_marbleQuickItem, SIGNAL(visibleLatLonAltBoxChanged()), 0209 m_autoNavigation, SLOT(inhibitAutoAdjustments()) ); 0210 } 0211 0212 if ( m_autoNavigation ) { 0213 m_autoNavigation->setRecenter( Marble::AutoNavigation::RecenterOnBorder ); 0214 } 0215 0216 emit autoCenterChanged(); 0217 } 0218 } 0219 0220 bool Tracking::autoZoom() const 0221 { 0222 if ( m_autoNavigation ) { 0223 return m_autoNavigation->autoZoom(); 0224 } 0225 0226 return false; 0227 } 0228 0229 void Tracking::setAutoZoom( bool enabled ) 0230 { 0231 if ( autoZoom() != enabled ) { 0232 if ( enabled && !m_autoNavigation && m_marbleQuickItem ) { 0233 m_autoNavigation = new Marble::AutoNavigation( m_marbleQuickItem->model(), m_marbleQuickItem->map()->viewport(), this ); 0234 connect( m_autoNavigation, SIGNAL(zoomIn(FlyToMode)), 0235 m_marbleQuickItem, SLOT(zoomIn()) ); 0236 connect( m_autoNavigation, SIGNAL(zoomOut(FlyToMode)), 0237 m_marbleQuickItem, SLOT(zoomOut()) ); 0238 connect( m_autoNavigation, SIGNAL(centerOn(GeoDataCoordinates,bool)), 0239 m_marbleQuickItem, SLOT(centerOn(GeoDataCoordinates)) ); 0240 0241 connect( m_marbleQuickItem, SIGNAL(visibleLatLonAltBoxChanged()), 0242 m_autoNavigation, SLOT(inhibitAutoAdjustments()) ); 0243 } 0244 0245 if ( m_autoNavigation ) { 0246 m_autoNavigation->setAutoZoom( enabled ); 0247 } 0248 0249 emit autoZoomChanged(); 0250 } 0251 } 0252 0253 Tracking::PositionMarkerType Tracking::positionMarkerType() const 0254 { 0255 return m_positionMarkerType; 0256 } 0257 0258 void Tracking::setPositionMarkerType( Tracking::PositionMarkerType type ) 0259 { 0260 setShowPositionMarkerPlugin( type == Arrow ); 0261 if ( type != m_positionMarkerType ) { 0262 m_positionMarkerType = type; 0263 emit positionMarkerTypeChanged(); 0264 } 0265 } 0266 0267 double Tracking::distance() const 0268 { 0269 return m_marbleQuickItem ? m_marbleQuickItem->model()->positionTracking()->length( m_marbleQuickItem->model()->planetRadius() ) : 0.0; 0270 } 0271 0272 void Tracking::saveTrack( const QString &fileName ) 0273 { 0274 if ( m_marbleQuickItem ) { 0275 /** @todo FIXME: replace the file:// prefix on QML side */ 0276 QString target = fileName.startsWith( QLatin1String( "file://" ) ) ? fileName.mid( 7 ) : fileName; 0277 m_marbleQuickItem->model()->positionTracking()->saveTrack( target ); 0278 } 0279 } 0280 0281 void Tracking::openTrack(const QString &fileName) 0282 { 0283 if ( m_marbleQuickItem ) { 0284 /** @todo FIXME: replace the file:// prefix on QML side */ 0285 QString target = fileName.startsWith( QLatin1String( "file://" ) ) ? fileName.mid( 7 ) : fileName; 0286 m_marbleQuickItem->model()->addGeoDataFile( target ); 0287 } 0288 } 0289 0290 void Tracking::clearTrack() 0291 { 0292 if ( m_marbleQuickItem ) { 0293 m_marbleQuickItem->model()->positionTracking()->clearTrack(); 0294 } 0295 } 0296 0297 } 0298 0299 #include "moc_Tracking.cpp"