Marble

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

KDE's Doxygen guidelines are available online.