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

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2019 Torsten Rahn <rahn@kde.org>
0004 //
0005 
0006 #include "GeoItem.h"
0007 #include "MarbleQuickItem.h"
0008 #include "Coordinate.h"
0009 
0010 #include "MarbleGlobal.h"
0011 
0012 using Marble::GeoDataCoordinates;
0013 using Marble::EARTH_RADIUS;
0014 using Marble::DEG2RAD;
0015 
0016 namespace Marble
0017 {
0018     GeoItem::GeoItem(QQuickItem *parent ) :
0019         QQuickItem( parent ),
0020         m_map(nullptr),
0021         m_observable(false),
0022         m_visible(true)
0023     {
0024         connect(this, &QQuickItem::parentChanged, this, &GeoItem::setMapToParentOnInit);
0025         connect(this, &QQuickItem::widthChanged, this, &GeoItem::updateScreenPosition);
0026         connect(this, &QQuickItem::heightChanged, this, &GeoItem::updateScreenPosition);
0027     }
0028 
0029     bool GeoItem::moveToScreenCoordinates(qreal x, qreal y)
0030     {
0031         bool valid = m_map->screenCoordinatesToGeoDataCoordinates(QPoint(x,y), m_coordinate);
0032         if (valid) {
0033             updateScreenPosition();
0034             emit longitudeChanged();
0035             emit latitudeChanged();
0036         }
0037         return valid;
0038     }
0039 
0040     qreal GeoItem::longitude() const
0041     {
0042         return m_coordinate.longitude( GeoDataCoordinates::Degree );
0043     }
0044 
0045     void GeoItem::setLongitude( qreal lon )
0046     {
0047         if (m_coordinate.longitude(GeoDataCoordinates::Degree) != lon) {
0048             m_coordinate.setLongitude( lon, GeoDataCoordinates::Degree );
0049             updateScreenPosition();
0050             emit longitudeChanged();
0051         }
0052     }
0053 
0054     qreal GeoItem::latitude() const
0055     {
0056         return m_coordinate.latitude( GeoDataCoordinates::Degree );
0057     }
0058 
0059     void GeoItem::setLatitude( qreal lat )
0060     {
0061         if (m_coordinate.latitude(GeoDataCoordinates::Degree) != lat) {
0062             m_coordinate.setLatitude( lat, GeoDataCoordinates::Degree );
0063             updateScreenPosition();
0064             emit latitudeChanged();
0065         }
0066     }
0067 
0068     qreal GeoItem::altitude() const
0069     {
0070         return m_coordinate.altitude();
0071     }
0072 
0073     void GeoItem::setAltitude( qreal alt )
0074     {
0075         if (m_coordinate.altitude() != alt) {
0076             m_coordinate.setAltitude( alt );
0077             updateScreenPosition();
0078             emit altitudeChanged();
0079         }
0080     }
0081 
0082     GeoDataCoordinates GeoItem::coordinates() const
0083     {
0084         return m_coordinate;
0085     }
0086 
0087     void GeoItem::setCoordinates( const GeoDataCoordinates &coordinates )
0088     {
0089         if (m_coordinate != coordinates) {
0090             m_coordinate = coordinates;
0091             updateScreenPosition();
0092         }
0093     }
0094 
0095     MarbleQuickItem *GeoItem::map() const
0096     {
0097         return m_map;
0098     }
0099 
0100     void GeoItem::setMap(MarbleQuickItem *map)
0101     {
0102         if (m_map == map)
0103             return;
0104 
0105         m_map = map;
0106 
0107         connect(m_map, &MarbleQuickItem::geoItemUpdateRequested, this, &GeoItem::updateScreenPosition);
0108         emit mapChanged(m_map);
0109     }
0110 
0111     void GeoItem::updateScreenPosition() {
0112         if (m_map) {
0113             QPointF relativePoint = m_map->screenCoordinatesFromGeoDataCoordinates(m_coordinate);
0114             bool observable = !relativePoint.isNull();
0115             if (observable != m_observable) {
0116                 m_observable = observable;
0117                 emit observableChanged(m_observable);
0118             }
0119             if (!m_coordinate.isValid()) {
0120                 setPosition(QPointF(-childrenRect().width(), -childrenRect().height()));
0121             }
0122             else if (observable) {
0123                 setPosition(QPointF(0.0,0.0));
0124                 QPointF screenPoint = mapFromItem(m_map, relativePoint);
0125                 screenPoint -= QPointF(width()/2.0, height()/2.0);
0126                 setPosition(screenPoint);
0127                 emit readonlyXChanged(readonlyX()) ;
0128                 emit readonlyYChanged(readonlyY()) ;
0129             }
0130             QQuickItem::setVisible(m_visible && m_observable);
0131         }
0132     }
0133 
0134     void GeoItem::setMapToParentOnInit()
0135     {
0136         MarbleQuickItem * visualParent = qobject_cast<MarbleQuickItem*>(parentItem());
0137         if (visualParent) {
0138             disconnect(this, &QQuickItem::parentChanged, this, &GeoItem::setMapToParentOnInit);
0139             setMap(visualParent);
0140         }
0141     }
0142 
0143     bool GeoItem::observable() const
0144     {
0145         return m_observable;
0146     }
0147 
0148     bool GeoItem::visObservable() const
0149     {
0150         return m_visible;
0151     }
0152 
0153     void GeoItem::setVisObservable(bool visible)
0154     {
0155         if (m_visible == visible)
0156             return;
0157 
0158         m_visible = visible;
0159         QQuickItem::setVisible(m_visible && m_observable);
0160         emit visObservableChanged(m_visible);
0161     }
0162 }
0163 
0164 #include "moc_GeoItem.cpp"