File indexing completed on 2024-05-05 03:49:47

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
0004 // SPDX-FileCopyrightText: 2012 Mohammed Nafees <nafees.technocool@gmail.com>
0005 //
0006 
0007 // self
0008 #include "BillboardGraphicsItem.h"
0009 #include "MarbleGraphicsItem_p.h"
0010 
0011 // Marble
0012 #include "ViewportParams.h"
0013 
0014 namespace Marble
0015 {
0016 
0017 class BillboardGraphicsItemPrivate : public MarbleGraphicsItemPrivate
0018 {
0019  public:
0020     BillboardGraphicsItemPrivate(BillboardGraphicsItem *parent)
0021         : MarbleGraphicsItemPrivate(parent),
0022         m_alignment( Qt::AlignHCenter | Qt::AlignVCenter )
0023     {
0024     }
0025 
0026     QVector<QPointF> positions() const override
0027     {
0028         return m_positions;
0029     }
0030 
0031     QVector<QPointF> absolutePositions() const override
0032     {
0033         return m_positions;
0034     }
0035 
0036     Qt::Alignment m_alignment;
0037 
0038     void setProjection(const ViewportParams *viewport) override
0039     {
0040         m_positions.clear();
0041 
0042         qreal x[100], y;
0043         int pointRepeatNumber = 0;
0044         bool globeHidesPoint;
0045 
0046         viewport->screenCoordinates( m_coordinates, x, y, pointRepeatNumber,
0047                                          m_size, globeHidesPoint );
0048 
0049         // Don't display items if they are on the far side of the globe.
0050         if (globeHidesPoint) return;
0051 
0052         m_positions.reserve(pointRepeatNumber);
0053         // handle vertical alignment
0054         qint32 topY = ( viewport->height() - m_size.height() ) / 2;
0055         if ( m_alignment & Qt::AlignTop ) {
0056             topY = y - m_size.height();
0057         }
0058         else if ( m_alignment & Qt::AlignVCenter ) {
0059             topY = y - ( m_size.height() / 2 );
0060         }
0061         else if ( m_alignment & Qt::AlignBottom ) {
0062             topY = y;
0063         }
0064 
0065         for ( int i = 0; i < pointRepeatNumber; ++i ) {
0066             // handle horizontal alignment
0067             qint32 leftX = ( viewport->width() - m_size.width() ) / 2;
0068             if ( m_alignment & Qt::AlignLeft ) {
0069                 leftX =  x[i] - m_size.width();
0070             }
0071             else if ( m_alignment & Qt::AlignHCenter ) {
0072                 leftX = x[i] - ( m_size.width() / 2 );
0073             }
0074             else if ( m_alignment & Qt::AlignRight ) {
0075                 leftX = x[i];
0076             }
0077 
0078             m_positions.append( QPoint( leftX, topY ) );
0079         }
0080     }
0081 
0082     GeoDataCoordinates m_coordinates;
0083     QVector<QPointF> m_positions;
0084 };
0085 
0086 BillboardGraphicsItem::BillboardGraphicsItem()
0087     : MarbleGraphicsItem(new BillboardGraphicsItemPrivate(this))
0088 {
0089 }
0090 
0091 GeoDataCoordinates BillboardGraphicsItem::coordinate() const
0092 {
0093     Q_D(const BillboardGraphicsItem);
0094     return d->m_coordinates;
0095 }
0096 
0097 void BillboardGraphicsItem::setCoordinate( const GeoDataCoordinates &coordinates )
0098 {
0099     Q_D(BillboardGraphicsItem);
0100     d->m_coordinates = coordinates;
0101 }
0102 
0103 QVector<QPointF> BillboardGraphicsItem::positions() const
0104 {
0105     Q_D(const BillboardGraphicsItem);
0106     return d->positions();
0107 }
0108 
0109 QVector<QRectF> BillboardGraphicsItem::boundingRects() const
0110 {
0111     Q_D(const BillboardGraphicsItem);
0112 
0113     QVector<QRectF> rects;
0114     rects.reserve(d->m_positions.size());
0115 
0116     QSizeF const size = d->m_size;
0117     for (const QPointF &point: d->m_positions) {
0118         rects << QRectF(point, size);
0119     }
0120     return rects;
0121 }
0122 
0123 QRectF BillboardGraphicsItem::containsRect( const QPointF &point ) const
0124 {
0125     for( const QRectF &rect: boundingRects() ) {
0126         if( rect.contains( point ) )
0127             return rect;
0128     }
0129 
0130     return QRectF();
0131 }
0132 
0133 Qt::Alignment BillboardGraphicsItem::alignment() const
0134 {
0135     Q_D(const BillboardGraphicsItem);
0136     return d->m_alignment;
0137 }
0138 
0139 void BillboardGraphicsItem::setAlignment(Qt::Alignment alignment)
0140 {
0141     Q_D(BillboardGraphicsItem);
0142     d->m_alignment = alignment;
0143 }
0144 
0145 } // Marble namespace