Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qgeoshape.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "qgeoshape.h"
6#include "qgeoshape_p.h"
8#include "qgeocircle.h"
9#include "qgeopath.h"
10#include "qgeopolygon.h"
11
12
13#ifndef QT_NO_DEBUG_STREAM
14#include <QtCore/QDebug>
15#endif
16
17#ifndef QT_NO_DATASTREAM
18#include <QtCore/QDataStream>
19#endif
20
21QT_BEGIN_NAMESPACE
22
23QT_IMPL_METATYPE_EXTERN(QGeoShape)
24
25QGeoShapePrivate::QGeoShapePrivate(QGeoShape::ShapeType type)
26: type(type)
27{
28}
29
30QGeoShapePrivate::~QGeoShapePrivate()
31{
32}
33
34bool QGeoShapePrivate::operator==(const QGeoShapePrivate &other) const
35{
36 return type == other.type;
37}
38
39/*!
40 \class QGeoShape
41 \inmodule QtPositioning
42 \ingroup QtPositioning-positioning
43 \since 5.2
44
45 \brief The QGeoShape class defines a geographic area.
46
47 This class is the base class for classes which specify a geographic
48 area.
49
50 For the sake of consistency, subclasses should describe the specific
51 details of the associated areas in terms of QGeoCoordinate instances
52 and distances in meters.
53
54 This class is also accessible in QML as \l[QML]{geoShape}.
55*/
56
57/*!
58 \enum QGeoShape::ShapeType
59
60 Describes the type of the shape.
61
62 \value UnknownType A shape of unknown type
63 \value RectangleType A rectangular shape
64 \value CircleType A circular shape
65 \value PathType A path type
66 \value PolygonType A polygon type
67*/
68
69/*!
70 \property QGeoShape::type
71 \brief This property holds the type of this geo shape.
72
73 While this property is introduced in Qt 5.5, the related accessor functions
74 exist since the first version of this class.
75
76 \since 5.5
77*/
78
79/*!
80 \property QGeoShape::isValid
81 \brief This property holds the validity of the geo shape.
82
83 A geo shape is considered to be invalid if some of the data that is required to
84 unambiguously describe the geo shape has not been set or has been set to an
85 unsuitable value depending on the subclass of this object. The default constructed
86 objects of this type are invalid.
87
88 While this property is introduced in Qt 5.5, the related accessor functions
89 exist since the first version of this class.
90
91 \since 5.5
92*/
93
94/*!
95 \property QGeoShape::isEmpty
96 \brief This property defines whether this geo shape is empty.
97
98 An empty geo shape is a region which has a geometrical area of 0.
99
100 While this property is introduced in Qt 5.5, the related accessor functions
101 exist since the first version of this class.
102
103 \since 5.5
104*/
105inline QGeoShapePrivate *QGeoShape::d_func()
106{
107 return static_cast<QGeoShapePrivate *>(d_ptr.data());
108}
109
110inline const QGeoShapePrivate *QGeoShape::d_func() const
111{
112 return static_cast<const QGeoShapePrivate *>(d_ptr.constData());
113}
114
115/*!
116 Constructs a new invalid geo shape of \l UnknownType.
117*/
118QGeoShape::QGeoShape()
119{
120}
121
122/*!
123 Constructs a new geo shape which is a copy of \a other.
124*/
125QGeoShape::QGeoShape(const QGeoShape &other)
126: d_ptr(other.d_ptr)
127{
128}
129
130/*!
131 \internal
132*/
133QGeoShape::QGeoShape(QGeoShapePrivate *d)
134: d_ptr(d)
135{
136}
137
138bool QGeoShape::equals(const QGeoShape &lhs, const QGeoShape &rhs)
139{
140 if (lhs.d_func() == rhs.d_func())
141 return true;
142
143 if (!lhs.d_func() || !rhs.d_func())
144 return false;
145
146 return *lhs.d_func() == *rhs.d_func();
147}
148
149/*!
150 Destroys this geo shape.
151*/
152QGeoShape::~QGeoShape()
153{
154}
155
156/*!
157 Returns the type of this geo shape.
158*/
159QGeoShape::ShapeType QGeoShape::type() const
160{
161 Q_D(const QGeoShape);
162
163 if (d)
164 return d->type;
165 else
166 return UnknownType;
167}
168
169/*!
170 Returns whether this geo shape is valid.
171
172*/
173bool QGeoShape::isValid() const
174{
175 Q_D(const QGeoShape);
176
177 if (d)
178 return d->isValid();
179 else
180 return false;
181}
182
183/*!
184 Returns whether this geo shape is empty.
185
186 An empty geo shape is a region which has a geometrical area of 0.
187*/
188bool QGeoShape::isEmpty() const
189{
190 Q_D(const QGeoShape);
191
192 if (d)
193 return d->isEmpty();
194 else
195 return true;
196}
197
198/*!
199 Returns whether the coordinate \a coordinate is contained within this geo shape.
200*/
201bool QGeoShape::contains(const QGeoCoordinate &coordinate) const
202{
203 Q_D(const QGeoShape);
204
205 if (d)
206 return d->contains(coordinate);
207 else
208 return false;
209}
210
211/*!
212 Returns a QGeoRectangle representing the geographical bounding rectangle of the
213 geo shape, that defines the latitudinal/longitudinal bounds of the geo shape.
214
215 \since 5.9
216*/
217QGeoRectangle QGeoShape::boundingGeoRectangle() const
218{
219 Q_D(const QGeoShape);
220
221 if (d)
222 return d->boundingGeoRectangle();
223 else
224 return QGeoRectangle();
225}
226
227/*!
228 \property QGeoShape::center
229 \brief the coordinate at the geometric center of the shape.
230*/
231
232/*!
233 Returns the coordinate located at the geometric center of the geo shape.
234
235 \since 5.5
236*/
237QGeoCoordinate QGeoShape::center() const
238{
239 Q_D(const QGeoShape);
240
241 if (d)
242 return d->center();
243 else
244 return QGeoCoordinate();
245}
246
247/*!
248 \fn bool QGeoShape::operator==(const QGeoShape &lhs, const QGeoShape &rhs)
249
250 Returns \c true if the \a lhs geo shape is equivalent to the \a rhs geo
251 shape, otherwise returns \c false.
252*/
253
254/*!
255 \fn bool QGeoShape::operator!=(const QGeoShape &lhs, const QGeoShape &rhs)
256
257 Returns \c true if the \a lhs geo shape is not equivalent to the \a rhs geo
258 shape, otherwise returns \c false.
259*/
260
261/*!
262 Assigns \a other to this geo shape and returns a reference to this geo shape.
263*/
264QGeoShape &QGeoShape::operator=(const QGeoShape &other)
265{
266 if (this == &other)
267 return *this;
268
269 d_ptr = other.d_ptr;
270 return *this;
271}
272
273/*!
274 Returns a string representation of this geo shape.
275
276 \since 5.5
277*/
278QString QGeoShape::toString() const
279{
280 return QStringLiteral("QGeoShape(%1)").arg(type());
281}
282
283#ifndef QT_NO_DEBUG_STREAM
284static void formatGeoCoordinates(QDebug dbg, const QList<QGeoCoordinate> &coordinates)
285{
286 const auto size = coordinates.size();
287 dbg << size << ": ";
288 for (qsizetype i = 0; i < size; ++i) {
289 if (i > 0)
290 dbg << "; ";
291 if (i > 10) {
292 dbg << "...";
293 break;
294 }
295 dbg << '(' << coordinates.at(i).toString() << ')';
296 }
297}
298
299QDebug QGeoShape::debugStreaming(QDebug dbg, const QGeoShape &shape)
300{
301 QDebugStateSaver saver(dbg);
302 dbg.nospace().noquote() << "QGeoShape(";
303 switch (shape.type()) {
304 case QGeoShape::UnknownType:
305 dbg << "Unknown";
306 break;
307 case QGeoShape::RectangleType: {
308 const auto &rect = static_cast<const QGeoRectangle &>(shape);
309 dbg << "Rectangle, (" << rect.topLeft().toString() << "), ("
310 << rect.bottomRight().toString() << ')';
311 break;
312 }
313 case QGeoShape::PathType:
314 dbg << "Path, ";
315 formatGeoCoordinates(dbg, static_cast<const QGeoPath &>(shape).path());
316 break;
317 case QGeoShape::PolygonType:
318 dbg << "Polygon, ";
319 formatGeoCoordinates(dbg, static_cast<const QGeoPolygon &>(shape).perimeter());
320 break;
321 case QGeoShape::CircleType: {
322 const auto &circle = static_cast<const QGeoCircle &>(shape);
323 dbg << "Circle, center=(" << circle.center().toString() << "), radius=" << circle.radius();
324 break;
325 }
326 }
327
328 dbg << ')';
329
330 return dbg;
331}
332#endif
333
334#ifndef QT_NO_DATASTREAM
335QDataStream &QGeoShape::dataStreamOut(QDataStream &stream, const QGeoShape &shape)
336{
337 stream << quint32(shape.type());
338 switch (shape.type()) {
339 case QGeoShape::UnknownType:
340 break;
341 case QGeoShape::RectangleType: {
342 QGeoRectangle r = shape;
343 stream << r.topLeft() << r.bottomRight();
344 break;
345 }
346 case QGeoShape::CircleType: {
347 QGeoCircle c = shape;
348 stream << c.center() << c.radius();
349 break;
350 }
351 case QGeoShape::PathType: {
352 QGeoPath p = shape;
353 stream << p.width();
354 stream << p.path().size();
355 for (const auto &c: p.path())
356 stream << c;
357 break;
358 }
359 case QGeoShape::PolygonType: {
360 QGeoPolygon p = shape;
361 stream << p.perimeter().size();
362 for (const auto &c: p.perimeter())
363 stream << c;
364 if (stream.version() >= QDataStream::Qt_6_10) {
365 // serialize holes
366 const qsizetype holesCount = p.holesCount();
367 stream << holesCount;
368 for (qsizetype i = 0; i < holesCount; ++i)
369 stream << p.holePath(i);
370 }
371 break;
372 }
373 }
374
375 return stream;
376}
377
378QDataStream &QGeoShape::dataStreamIn(QDataStream &stream, QGeoShape &shape)
379{
380 quint32 type;
381 stream >> type;
382
383 switch (type) {
384 case QGeoShape::UnknownType:
385 shape = QGeoShape();
386 break;
387 case QGeoShape::RectangleType: {
388 QGeoCoordinate tl;
389 QGeoCoordinate br;
390 stream >> tl >> br;
391 shape = QGeoRectangle(tl, br);
392 break;
393 }
394 case QGeoShape::CircleType: {
395 QGeoCoordinate c;
396 qreal r;
397 stream >> c >> r;
398 shape = QGeoCircle(c, r);
399 break;
400 }
401 case QGeoShape::PathType: {
402 QList<QGeoCoordinate> l;
403 QGeoCoordinate c;
404 qreal width;
405 stream >> width;
406 qsizetype sz;
407 stream >> sz;
408 for (qsizetype i = 0; i < sz; i++) {
409 stream >> c;
410 l.append(c);
411 }
412 shape = QGeoPath(l, width);
413 break;
414 }
415 case QGeoShape::PolygonType: {
416 QList<QGeoCoordinate> l;
417 QGeoCoordinate c;
418 qsizetype sz;
419 stream >> sz;
420 for (qsizetype i = 0; i < sz; i++) {
421 stream >> c;
422 l.append(c);
423 }
424 QGeoPolygon p(l);
425 if (stream.version() >= QDataStream::Qt_6_10) {
426 // deserialize holes
427 qsizetype holesCount = 0;
428 stream >> holesCount;
429 for (qsizetype i = 0; i < holesCount; ++i) {
430 QList<QGeoCoordinate> holePath;
431 stream >> holePath;
432 p.addHole(holePath);
433 }
434 }
435 shape = p;
436 break;
437 }
438 }
439
440 return stream;
441}
442#endif
443
444/*!
445 \relates QGeoShape
446
447 Returns the hash value for the \a shape, using \a seed for the
448 calculation.
449*/
450size_t qHash(const QGeoShape &shape, size_t seed) noexcept
451{
452 if (shape.d_ptr)
453 return shape.d_ptr->hash(seed);
454 else
455 return qHashMulti(seed, shape.type());
456}
457
458QT_END_NAMESPACE
459
460#include "moc_qgeoshape.cpp"
static void formatGeoCoordinates(QDebug dbg, const QList< QGeoCoordinate > &coordinates)
constexpr size_t qHash(const QSize &s, size_t seed=0) noexcept
Definition qsize.h:192