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"