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 }