Marble

GeoDataLatLonAltBox.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2007 Andrew Manson <g.real.ate@gmail.com>
4// SPDX-FileCopyrightText: 2008 Torsten Rahn <rahn@kde.org>
5//
6
7
8#include "GeoDataLatLonAltBox.h"
9
10#include "MarbleDebug.h"
11#include "GeoDataCoordinates.h"
12#include "GeoDataLineString.h"
13
14#include "GeoDataTypes.h"
15
16#include <QDataStream>
17
18namespace Marble
19{
20
21class GeoDataLatLonAltBoxPrivate
22{
23 public:
24 GeoDataLatLonAltBoxPrivate()
25 : m_minAltitude( 0 ),
26 m_maxAltitude( 0 ),
27 m_altitudeMode( ClampToGround )
28 {
29 }
30
31 qreal m_minAltitude;
32 qreal m_maxAltitude;
33 AltitudeMode m_altitudeMode;
34};
35
36bool operator==( GeoDataLatLonAltBox const& lhs, GeoDataLatLonAltBox const& rhs )
37{
38 return lhs.west() == rhs.west() &&
39 lhs.east() == rhs.east() &&
40 lhs.north() == rhs.north() &&
41 lhs.south() == rhs.south() &&
42 lhs.rotation() == rhs.rotation() &&
43 lhs.d->m_minAltitude == rhs.d->m_minAltitude &&
44 lhs.d->m_maxAltitude == rhs.d->m_maxAltitude &&
45 lhs.d->m_altitudeMode == rhs.d->m_altitudeMode;
46}
47
48GeoDataLatLonAltBox& GeoDataLatLonAltBox::operator=( const GeoDataLatLonAltBox &other )
49{
50 GeoDataLatLonBox::operator=( other );
51
52 *d = *other.d;
53 return *this;
54}
55
56GeoDataLatLonAltBox& GeoDataLatLonAltBox::operator=( const GeoDataCoordinates &other )
57{
58 setWest( other.longitude() );
59 setEast( other.longitude() );
60 setNorth( other.latitude() );
61 setSouth( other.latitude() );
62 setMinAltitude( other.altitude() );
63 setMaxAltitude( other.altitude() );
64 return *this;
65}
66
67GeoDataLatLonAltBox::GeoDataLatLonAltBox()
68 : GeoDataLatLonBox(),
69 d( new GeoDataLatLonAltBoxPrivate )
70{
71}
72
73GeoDataLatLonAltBox::GeoDataLatLonAltBox( const GeoDataLatLonAltBox & other )
74 : GeoDataLatLonBox( other ),
75 d( new GeoDataLatLonAltBoxPrivate( *other.d ))
76{
77}
78
79GeoDataLatLonAltBox::GeoDataLatLonAltBox( const GeoDataLatLonBox &other, qreal minAltitude, qreal maxAltitude )
80 : GeoDataLatLonBox( other ),
81 d( new GeoDataLatLonAltBoxPrivate )
82{
83 setWest( other.west() );
84 setEast( other.east() );
85 setNorth( other.north() );
86 setSouth( other.south() );
87 setRotation( other.rotation() );
88
89 d->m_minAltitude = minAltitude;
90 d->m_maxAltitude = maxAltitude;
91}
92
93
94GeoDataLatLonAltBox::GeoDataLatLonAltBox( const GeoDataCoordinates & coordinates )
96 d( new GeoDataLatLonAltBoxPrivate )
97{
98 setWest( coordinates.longitude() );
99 setEast( coordinates.longitude() );
100 setNorth( coordinates.latitude() );
101 setSouth( coordinates.latitude() );
102
103 d->m_minAltitude = coordinates.altitude();
104 d->m_maxAltitude = coordinates.altitude();
105}
106
107
108GeoDataLatLonAltBox::~GeoDataLatLonAltBox()
109{
110 delete d;
111}
112
114{
115 return GeoDataTypes::GeoDataLatLonAltBoxType;
116}
117
119{
120 return d->m_minAltitude;
121}
122
123void GeoDataLatLonAltBox::setMinAltitude( const qreal minAltitude )
124{
125 d->m_minAltitude = minAltitude;
126}
127
129{
130 return d->m_maxAltitude;
131}
132
133void GeoDataLatLonAltBox::setMaxAltitude( const qreal maxAltitude )
134{
135 d->m_maxAltitude = maxAltitude;
136}
137
139{
140 return d->m_altitudeMode;
141}
142
144{
145 if ( isEmpty() )
146 return GeoDataCoordinates();
147 if( crossesDateLine() )
148 return GeoDataCoordinates( GeoDataCoordinates::normalizeLon(east() + 2 * M_PI - (east() + 2 * M_PI - west()) / 2),
149 north() - (north() - south()) / 2,
150 d->m_maxAltitude - (d->m_maxAltitude - d->m_minAltitude) / 2);
151 else
152 return GeoDataCoordinates( east() - (east() - west()) / 2,
153 north() - (north() - south()) / 2,
154 d->m_maxAltitude - (d->m_maxAltitude - d->m_minAltitude) / 2);
155}
156
157void GeoDataLatLonAltBox::setAltitudeMode( const AltitudeMode altitudeMode )
158{
159 d->m_altitudeMode = altitudeMode;
160}
161
162bool GeoDataLatLonAltBox::contains( const GeoDataCoordinates &point ) const
163{
164 if ( !GeoDataLatLonBox::contains( point ) )
165 return false;
166
167 if ( point.altitude() < d->m_minAltitude || point.altitude() > d->m_maxAltitude ) {
168 return false;
169 }
170
171 return true;
172}
173
174bool GeoDataLatLonAltBox::contains( const GeoDataLatLonAltBox &other ) const
175{
176 // check the contain criterion for the altitude first as this is trivial:
177
178 // mDebug() << "this " << this->toString(GeoDataCoordinates::Degree);
179 // mDebug() << "other" << other.toString(GeoDataCoordinates::Degree);
180
181 if ( d->m_maxAltitude >= other.maxAltitude() && d->m_minAltitude <= other.minAltitude() ) {
182 return GeoDataLatLonBox::contains( other );
183 }
184
185 return false;
186}
187
189{
190 // Case 1: maximum altitude of other box intersects:
191 if ( ( d->m_maxAltitude >= other.maxAltitude() && d->m_minAltitude <= other.maxAltitude() )
192 // Case 2: maximum altitude of this box intersects:
193 || ( other.maxAltitude() >= d->m_maxAltitude && other.minAltitude() <= d->m_maxAltitude )
194 // Case 3: minimum altitude of other box intersects:
195 || ( d->m_maxAltitude >= other.minAltitude() && d->m_minAltitude <= other.minAltitude() )
196 // Case 4: minimum altitude of this box intersects:
197 || ( other.maxAltitude() >= d->m_minAltitude && other.minAltitude() <= d->m_minAltitude ) ) {
198
199 if ( GeoDataLatLonBox::intersects( other ) )
200 return true;
201
202 }
203
204 return false;
205}
206
208{
209 // If the line string is empty return a boundingbox that contains everything
210 if ( lineString.size() == 0 ) {
211 return GeoDataLatLonAltBox();
212 }
213
214 const qreal altitude = lineString.first().altitude();
215
216 GeoDataLatLonAltBox temp ( GeoDataLatLonBox::fromLineString( lineString ), altitude, altitude );
217
218 qreal maxAltitude = altitude;
219 qreal minAltitude = altitude;
220
221 // If there's only a single node stored then the boundingbox only contains that point
222 if ( lineString.size() == 1 ) {
223 temp.setMinAltitude( minAltitude );
224 temp.setMaxAltitude( maxAltitude );
225 return temp;
226 }
227
230
231 for ( ; it != itEnd; ++it )
232 {
233 // Get coordinates and normalize them to the desired range.
234 const qreal altitude = (it)->altitude();
235
236 // Determining the maximum and minimum altitude
237 if ( altitude > maxAltitude ) {
238 maxAltitude = altitude;
239 } else if ( altitude < minAltitude ) {
240 minAltitude = altitude;
241 }
242 }
243
244 temp.setMinAltitude( minAltitude );
245 temp.setMaxAltitude( maxAltitude );
246 return temp;
247}
248
250{
251 return GeoDataLatLonBox::isNull() && d->m_maxAltitude == d->m_minAltitude;
252}
253
255{
257 d->m_minAltitude = 0;
258 d->m_maxAltitude = 0;
259 d->m_altitudeMode = ClampToGround;
260}
261
263{
264 GeoDataObject::pack( stream );
265
266 stream << d->m_minAltitude << d->m_maxAltitude;
267 stream << d->m_altitudeMode;
268}
269
271{
272 GeoDataObject::unpack( stream );
273
274 stream >> d->m_minAltitude >> d->m_maxAltitude;
275 int a;
276 stream >> a;
277 d->m_altitudeMode = static_cast<AltitudeMode>( a );
278}
279
280uint qHash(const GeoDataLatLonAltBox &box, uint seed)
281{
282 seed = ::qHash(box.east(), seed);
283 seed = ::qHash(box.west(), seed);
284 seed = ::qHash(box.south(), seed);
285 seed = ::qHash(box.north(), seed);
286 seed = ::qHash(box.maxAltitude(), seed);
287
288 return ::qHash(box.minAltitude(), seed);
289}
290
291}
A 3d point representation.
static qreal normalizeLon(qreal lon, GeoDataCoordinates::Unit=GeoDataCoordinates::Radian)
normalize the longitude to always be -M_PI <= lon <= +M_PI (Radian).
qreal altitude() const
return the altitude of the Point in meters
qreal longitude(GeoDataCoordinates::Unit unit) const
retrieves the longitude of the GeoDataCoordinates object use the unit parameter to switch between Rad...
qreal latitude(GeoDataCoordinates::Unit unit) const
retrieves the latitude of the GeoDataCoordinates object use the unit parameter to switch between Radi...
A class that defines a 3D bounding box for geographic data.
qreal minAltitude() const
Get the lower altitude boundary of the bounding box.
void clear() override
Resets the bounding box to its uninitialised state (and thus contains nothing).
const char * nodeType() const override
Provides type information for downcasting a GeoData.
void unpack(QDataStream &stream) override
Unserialize the contents of the feature from stream.
virtual bool intersects(const GeoDataLatLonAltBox &) const
Check if this GeoDataLatLonAltBox intersects with the given one.
bool isNull() const override
Indicates whether the bounding box only contains a single 2D point ("singularity").
qreal maxAltitude() const
Get the upper altitude boundary of the bounding box.
static GeoDataLatLonAltBox fromLineString(const GeoDataLineString &lineString)
Create the smallest bounding box from a line string.
GeoDataCoordinates center() const override
returns the center of this box
AltitudeMode altitudeMode() const
Get the reference system for the altitude.
void pack(QDataStream &stream) const override
Serialize the contents of the feature to stream.
A class that defines a 2D bounding box for geographic data.
qreal north(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the northern boundary of the bounding box.
qreal east(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the eastern boundary of the bounding box.
virtual bool isEmpty() const
Indicates whether the bounding box is not initialised (and contains nothing).
virtual bool isNull() const
Indicates whether the bounding box only contains a single 2D point ("singularity").
qreal west(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the western boundary of the bounding box.
qreal south(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the southern boundary of the bounding box.
bool crossesDateLine() const
Detect whether the bounding box crosses the IDL.
static GeoDataLatLonBox fromLineString(const GeoDataLineString &lineString)
Create the smallest bounding box from a line string.
virtual void clear()
Resets the bounding box to its uninitialised state (and thus contains nothing).
A LineString that allows to store a contiguous set of line segments.
QVector< GeoDataCoordinates >::ConstIterator constEnd() const
Returns a const iterator that points to the end of the LineString.
GeoDataCoordinates & first()
Returns a reference to the first node in the LineString. This method detaches the returned coordinate...
int size() const
Returns the number of nodes in a LineString.
QVector< GeoDataCoordinates >::ConstIterator constBegin() const
Returns a const iterator that points to the begin of the LineString.
void pack(QDataStream &stream) const override
Reimplemented from Serializable.
void unpack(QDataStream &steam) override
Reimplemented from Serializable.
Binds a QML item to a specific geodetic location in screen coordinates.
@ ClampToGround
Altitude always sticks to ground level.
bool operator==(const QGraphicsApiFilter &reference, const QGraphicsApiFilter &sample)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:17 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.