File indexing completed on 2024-04-28 03:50:12
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2010 Wes Hardaker <marble@ws6z.com> 0004 // 0005 0006 #include "AprsObject.h" 0007 0008 0009 #include "MarbleColors.h" 0010 #include "MarbleDebug.h" 0011 #include "MarbleDirs.h" 0012 #include "GeoDataLineString.h" 0013 #include "GeoPainter.h" 0014 0015 using namespace Marble; 0016 0017 AprsObject::AprsObject( const GeoAprsCoordinates &at, const QString &name ) 0018 : m_myName( name ), 0019 m_seenFrom( at.seenFrom() ), 0020 m_havePixmap ( false ), 0021 m_pixmapFilename( ), 0022 m_pixmap( nullptr ) 0023 { 0024 m_history.push_back( at ); 0025 } 0026 0027 AprsObject::~AprsObject() 0028 { 0029 delete m_pixmap; 0030 } 0031 0032 GeoAprsCoordinates 0033 AprsObject::location() const 0034 { 0035 return m_history.last(); 0036 } 0037 0038 void 0039 AprsObject::setLocation( const GeoAprsCoordinates &location ) 0040 { 0041 // Not ideal but it's unlikely they'll jump to the *exact* same spot again 0042 if ( !m_history.contains( location ) ) { 0043 m_history.push_back( location ); 0044 mDebug() << " moved: " << m_myName.toLocal8Bit().data(); 0045 } else { 0046 int index = m_history.indexOf( location ); 0047 m_history[index].resetTimestamp(); 0048 m_history[index].addSeenFrom( location.seenFrom() ); 0049 } 0050 0051 m_seenFrom = ( m_seenFrom | location.seenFrom() ); 0052 } 0053 0054 void 0055 AprsObject::setPixmapId( QString &pixmap ) 0056 { 0057 QString pixmapFilename = MarbleDirs::path( pixmap ); 0058 if ( QFile( pixmapFilename ).exists() ) { 0059 m_havePixmap = true; 0060 m_pixmapFilename = pixmapFilename; 0061 // We can't load the pixmap here since it's used in a different thread 0062 } 0063 else { 0064 m_havePixmap = false; 0065 } 0066 } 0067 0068 QColor 0069 AprsObject::calculatePaintColor( int from, const QElapsedTimer &time, int fadeTime ) 0070 { 0071 QColor color; 0072 if ( from & GeoAprsCoordinates::Directly ) { 0073 color = Oxygen::emeraldGreen4; // oxygen green if direct 0074 } else if ( (from & ( GeoAprsCoordinates::FromTCPIP | GeoAprsCoordinates::FromTTY ) ) == ( GeoAprsCoordinates::FromTCPIP | GeoAprsCoordinates::FromTTY ) ) { 0075 color = Oxygen::burgundyPurple4; // oxygen purple if both 0076 } else if ( from & GeoAprsCoordinates::FromTCPIP ) { 0077 color = Oxygen::brickRed4; // oxygen red if net 0078 } else if ( from & GeoAprsCoordinates::FromTTY ) { 0079 color = Oxygen::seaBlue4; // oxygen blue if TNC TTY relay 0080 } else if ( from & ( GeoAprsCoordinates::FromFile ) ) { 0081 color = Oxygen::sunYellow3; // oxygen yellow if file only 0082 } else { 0083 mDebug() << "**************************************** unknown from: " 0084 << from; 0085 color = Oxygen::aluminumGray5; // shouldn't happen but a user 0086 // could mess up I suppose we 0087 // should at least draw it in 0088 // something. 0089 } 0090 0091 if ( fadeTime > 0 && time.elapsed() > fadeTime ) { // 5 min ( 600000 ms ) 0092 color.setAlpha( 160 ); 0093 } 0094 0095 return color; 0096 } 0097 0098 void 0099 AprsObject::render( GeoPainter *painter, ViewportParams *viewport, 0100 int fadeTime, int hideTime ) 0101 { 0102 Q_UNUSED( viewport ); 0103 0104 if ( hideTime > 0 && m_history.last().timestamp().elapsed() > hideTime ) 0105 return; 0106 0107 QColor baseColor = calculatePaintColor( m_seenFrom, 0108 m_history.last().timestamp(), 0109 fadeTime ); 0110 0111 if ( m_history.count() > 1 ) { 0112 0113 QList<GeoAprsCoordinates>::iterator spot = m_history.begin(); 0114 QList<GeoAprsCoordinates>::iterator endSpot = m_history.end(); 0115 0116 GeoDataLineString lineString; 0117 lineString.setTessellate( true ); 0118 lineString << *spot; // *spot exists because m_history.count() > 1 0119 0120 for( ++spot; spot != endSpot; ++spot ) { 0121 0122 if ( hideTime > 0 && ( *spot ).timestamp().elapsed() > hideTime ) 0123 break; 0124 0125 lineString << *spot; 0126 0127 // draw the new circle in whatever is appropriate for that point 0128 const QColor penColor = calculatePaintColor( spot->seenFrom(), spot->timestamp(), fadeTime ); 0129 painter->setPen( penColor ); 0130 painter->drawRect( *spot, 5, 5 ); 0131 } 0132 0133 // draw the line in the base color 0134 painter->setPen( baseColor ); 0135 painter->drawPolyline( lineString ); 0136 } 0137 0138 0139 // Always draw the symbol then the text last so it's on top 0140 if ( m_havePixmap ) { 0141 if ( ! m_pixmap ) 0142 m_pixmap = new QPixmap ( m_pixmapFilename ); 0143 if ( m_pixmap && ! m_pixmap->isNull() ) 0144 painter->drawPixmap( m_history.last(), *m_pixmap ); 0145 else 0146 painter->drawRect( m_history.last(), 6, 6 ); 0147 } 0148 else 0149 painter->drawRect( m_history.last(), 6, 6 ); 0150 0151 painter->setPen( baseColor ); 0152 painter->drawText( m_history.last(), m_myName ); 0153 }