File indexing completed on 2024-12-08 06:35:36

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
0004 // SPDX-FileCopyrightText: 2011-2012 Florian Eßer <f.esser@rwth-aachen.de>
0005 //
0006 
0007 #include "ElevationProfileMarker.h"
0008 
0009 #include "MarbleLocale.h"
0010 #include "MarbleModel.h"
0011 #include "GeoDataDocument.h"
0012 #include "GeoDataPlacemark.h"
0013 #include "GeoPainter.h"
0014 #include "GeoDataTreeModel.h"
0015 #include "ViewportParams.h"
0016 #include "MarbleGraphicsGridLayout.h"
0017 
0018 #include <QRect>
0019 #include <QIcon>
0020 
0021 namespace Marble
0022 {
0023 
0024 ElevationProfileMarker::ElevationProfileMarker( const MarbleModel *marbleModel )
0025         : RenderPlugin( marbleModel ),
0026         m_markerPlacemark( nullptr ),
0027         m_markerItem(),
0028         m_markerIcon( &m_markerItem ),
0029         m_markerText( &m_markerItem )
0030 {
0031     if ( !marbleModel ) {
0032         return;
0033     }
0034     setVisible( false );
0035     m_markerItem.setCacheMode( MarbleGraphicsItem::ItemCoordinateCache );
0036 
0037     connect( const_cast<MarbleModel *>( marbleModel )->treeModel(), SIGNAL(added(GeoDataObject*)),
0038              this, SLOT(onGeoObjectAdded(GeoDataObject*)) );
0039     connect( const_cast<MarbleModel *>( marbleModel )->treeModel(), SIGNAL(removed(GeoDataObject*)),
0040              this, SLOT(onGeoObjectRemoved(GeoDataObject*)) );
0041 }
0042 
0043 ElevationProfileMarker::~ElevationProfileMarker()
0044 {
0045 }
0046 
0047 QStringList ElevationProfileMarker::backendTypes() const
0048 {
0049     return QStringList(QStringLiteral("elevationprofilemarker"));
0050 }
0051 
0052 QString ElevationProfileMarker::renderPolicy() const
0053 {
0054     return QStringLiteral("ALWAYS");
0055 }
0056 
0057 QStringList ElevationProfileMarker::renderPosition() const
0058 {
0059     return QStringList(QStringLiteral("HOVERS_ABOVE_SURFACE"));
0060 }
0061 
0062 qreal ElevationProfileMarker::zValue() const
0063 {
0064     return 3.0;
0065 }
0066 
0067 QString ElevationProfileMarker::name() const
0068 {
0069     return tr( "Elevation Profile Marker" );
0070 }
0071 
0072 QString ElevationProfileMarker::guiString() const
0073 {
0074     return tr( "&Elevation Profile Marker" );
0075 }
0076 
0077 QString ElevationProfileMarker::nameId() const
0078 {
0079     return QStringLiteral("elevationprofilemarker");
0080 }
0081 
0082 QString ElevationProfileMarker::version() const
0083 {
0084     return QStringLiteral("1.0");
0085 }
0086 
0087 QString ElevationProfileMarker::description() const
0088 {
0089     return tr( "Marks the current elevation of the elevation profile on the map." );
0090 }
0091 
0092 QString ElevationProfileMarker::copyrightYears() const
0093 {
0094     return QStringLiteral("2011, 2012");
0095 }
0096 
0097 QVector<PluginAuthor> ElevationProfileMarker::pluginAuthors() const
0098 {
0099     return QVector<PluginAuthor>()
0100             << PluginAuthor(QStringLiteral("Bernhard Beschow"), QStringLiteral("bbeschow@cs.tu-berlin.de"))
0101             << PluginAuthor(QStringLiteral("Florian Eßer"), QStringLiteral("f.esser@rwth-aachen.de"));
0102 }
0103 
0104 QIcon ElevationProfileMarker::icon() const
0105 {
0106     return QIcon(QStringLiteral(":/icons/elevationprofile.png"));
0107 }
0108 
0109 void ElevationProfileMarker::initialize()
0110 {
0111     m_markerIcon.setImage(QImage(QStringLiteral(":/flag-red-mirrored.png")));
0112 
0113     MarbleGraphicsGridLayout *topLayout = new MarbleGraphicsGridLayout( 1, 2 );
0114     m_markerItem.setLayout( topLayout );
0115     topLayout->addItem( &m_markerIcon, 0, 0 );
0116 
0117     m_markerText.setFrame( LabelGraphicsItem::RoundedRectFrame );
0118     m_markerText.setPadding( 1 );
0119     topLayout->addItem( &m_markerText, 0, 1 );
0120 }
0121 
0122 bool ElevationProfileMarker::isInitialized() const
0123 {
0124     return !m_markerIcon.image().isNull();
0125 }
0126 
0127 bool ElevationProfileMarker::render( GeoPainter* painter, ViewportParams* viewport, const QString& renderPos, GeoSceneLayer* layer )
0128 {
0129     Q_UNUSED( renderPos )
0130     Q_UNUSED( layer )
0131 
0132     if ( !m_markerPlacemark )
0133         return true;
0134 
0135     if ( m_currentPosition != m_markerPlacemark->coordinate() ) {
0136         m_currentPosition = m_markerPlacemark->coordinate();
0137 
0138         if ( m_currentPosition.isValid() ) {
0139             QString unitString = tr( "m" );
0140             int displayScale = 1.0;
0141             const MarbleLocale::MeasurementSystem measurementSystem =
0142                     MarbleGlobal::getInstance()->locale()->measurementSystem();
0143             switch ( measurementSystem ) {
0144             case MarbleLocale::MetricSystem:
0145                 /* nothing to do */
0146                 break;
0147             case MarbleLocale::ImperialSystem:
0148                 unitString = tr( "ft" );
0149                 displayScale = M2FT;
0150                 break;
0151             case MarbleLocale::NauticalSystem:
0152                 unitString = tr("ft");
0153                 displayScale = 0.001 * KM2NM * NM2FT;
0154             }
0155 
0156             QString intervalStr;
0157             intervalStr.setNum( m_currentPosition.altitude() * displayScale, 'f', 1 );
0158             intervalStr += QLatin1Char(' ') + unitString;
0159             m_markerText.setText( intervalStr );
0160         }
0161     }
0162 
0163     if ( m_currentPosition.isValid() ) {
0164         qreal x;
0165         qreal y;
0166         qreal lon;
0167         qreal lat;
0168         // move the icon by some pixels, so that the pole of the flag sits at the exact point
0169         int dx = +3 + m_markerItem.size().width() / 2 - m_markerIcon.contentRect().right();//-4;
0170         int dy = -6;
0171         viewport->screenCoordinates( m_currentPosition.longitude( GeoDataCoordinates::Radian ),
0172                                      m_currentPosition.latitude ( GeoDataCoordinates::Radian ),
0173                                      x, y );
0174         viewport->geoCoordinates( x + dx, y + dy, lon, lat, GeoDataCoordinates::Radian );
0175         m_markerItem.setCoordinate( GeoDataCoordinates( lon, lat, m_currentPosition.altitude(),
0176                                                             GeoDataCoordinates::Radian ) );
0177 
0178         painter->save();
0179 
0180         m_markerItem.paintEvent( painter, viewport );
0181 
0182         painter->restore();
0183     }
0184 
0185     return true;
0186 }
0187 
0188 void ElevationProfileMarker::onGeoObjectAdded( GeoDataObject *object )
0189 {
0190     if ( m_markerPlacemark )
0191         return;
0192 
0193     GeoDataDocument *document = dynamic_cast<GeoDataDocument *>( object );
0194 
0195     if ( !document )
0196         return;
0197 
0198     if (document->name() != QLatin1String("Elevation Profile"))
0199         return;
0200 
0201     if (document->isEmpty())
0202         return;
0203 
0204     m_markerPlacemark = dynamic_cast<GeoDataPlacemark *>( document->child( 0 ) );
0205 
0206     setVisible( m_markerPlacemark != nullptr );
0207 }
0208 
0209 void ElevationProfileMarker::onGeoObjectRemoved( GeoDataObject *object )
0210 {
0211     GeoDataDocument *const document = dynamic_cast<GeoDataDocument *>( object );
0212     if ( !document )
0213         return;
0214 
0215     if (document->name() != QLatin1String("Elevation Profile"))
0216         return;
0217 
0218     m_markerPlacemark = nullptr;
0219 
0220     emit repaintNeeded();
0221 }
0222 
0223 }
0224 
0225 #include "moc_ElevationProfileMarker.cpp"