1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtPositioning module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qgeoshape.h"
41 #include "qgeoshape_p.h"
42 #include "qgeorectangle.h"
43 #include "qgeocircle.h"
44 #include "qgeopath.h"
45 #include "qgeopolygon.h"
46 
47 
48 #ifndef QT_NO_DEBUG_STREAM
49 #include <QtCore/QDebug>
50 #endif
51 
52 #ifndef QT_NO_DATASTREAM
53 #include <QtCore/QDataStream>
54 #endif
55 
56 QT_BEGIN_NAMESPACE
57 
QGeoShapePrivate(QGeoShape::ShapeType type)58 QGeoShapePrivate::QGeoShapePrivate(QGeoShape::ShapeType type)
59 :   type(type)
60 {
61 }
62 
~QGeoShapePrivate()63 QGeoShapePrivate::~QGeoShapePrivate()
64 {
65 }
66 
operator ==(const QGeoShapePrivate & other) const67 bool QGeoShapePrivate::operator==(const QGeoShapePrivate &other) const
68 {
69     return type == other.type;
70 }
71 
72 /*!
73     \class QGeoShape
74     \inmodule QtPositioning
75     \ingroup QtPositioning-positioning
76     \since 5.2
77 
78     \brief The QGeoShape class defines a geographic area.
79 
80     This class is the base class for classes which specify a geographic
81     area.
82 
83     For the sake of consistency, subclasses should describe the specific
84     details of the associated areas in terms of QGeoCoordinate instances
85     and distances in meters.
86 
87     This class is a \l Q_GADGET since Qt 5.5. It can be
88     \l{Cpp_value_integration_positioning}{directly used from C++ and QML}.
89 */
90 
91 /*!
92     \enum QGeoShape::ShapeType
93 
94     Describes the type of the shape.
95 
96     \value UnknownType      A shape of unknown type
97     \value RectangleType    A rectangular shape
98     \value CircleType       A circular shape
99     \value PathType         A path type
100     \value PolygonType      A polygon type
101 */
102 
103 /*!
104     \property QGeoShape::type
105     \brief This property holds the type of this geo shape.
106 
107     While this property is introduced in Qt 5.5, the related accessor functions
108     exist since the first version of this class.
109 
110     \since 5.5
111 */
112 
113 /*!
114     \property QGeoShape::isValid
115     \brief This property holds the validity of the geo shape.
116 
117     A geo shape is considered to be invalid if some of the data that is required to
118     unambiguously describe the geo shape has not been set or has been set to an
119     unsuitable value depending on the subclass of this object. The default constructed
120     objects of this type are invalid.
121 
122     While this property is introduced in Qt 5.5, the related accessor functions
123     exist since the first version of this class.
124 
125     \since 5.5
126 */
127 
128 /*!
129     \property QGeoShape::isEmpty
130     \brief This property defines whether this geo shape is empty.
131 
132     An empty geo shape is a region which has a geometrical area of 0.
133 
134     While this property is introduced in Qt 5.5, the related accessor functions
135     exist since the first version of this class.
136 
137     \since 5.5
138 */
d_func()139 inline QGeoShapePrivate *QGeoShape::d_func()
140 {
141     return static_cast<QGeoShapePrivate *>(d_ptr.data());
142 }
143 
d_func() const144 inline const QGeoShapePrivate *QGeoShape::d_func() const
145 {
146     return static_cast<const QGeoShapePrivate *>(d_ptr.constData());
147 }
148 
149 /*!
150     Constructs a new invalid geo shape of \l UnknownType.
151 */
QGeoShape()152 QGeoShape::QGeoShape()
153 {
154 }
155 
156 /*!
157     Constructs a new geo shape which is a copy of \a other.
158 */
QGeoShape(const QGeoShape & other)159 QGeoShape::QGeoShape(const QGeoShape &other)
160 :   d_ptr(other.d_ptr)
161 {
162 }
163 
164 /*!
165     \internal
166 */
QGeoShape(QGeoShapePrivate * d)167 QGeoShape::QGeoShape(QGeoShapePrivate *d)
168 :   d_ptr(d)
169 {
170 }
171 
172 /*!
173     Destroys this geo shape.
174 */
~QGeoShape()175 QGeoShape::~QGeoShape()
176 {
177 }
178 
179 /*!
180     Returns the type of this geo shape.
181 */
type() const182 QGeoShape::ShapeType QGeoShape::type() const
183 {
184     Q_D(const QGeoShape);
185 
186     if (d)
187         return d->type;
188     else
189         return UnknownType;
190 }
191 
192 /*!
193     Returns whether this geo shape is valid.
194 
195 */
isValid() const196 bool QGeoShape::isValid() const
197 {
198     Q_D(const QGeoShape);
199 
200     if (d)
201         return d->isValid();
202     else
203         return false;
204 }
205 
206 /*!
207     Returns whether this geo shape is empty.
208 
209     An empty geo shape is a region which has a geometrical area of 0.
210 */
isEmpty() const211 bool QGeoShape::isEmpty() const
212 {
213     Q_D(const QGeoShape);
214 
215     if (d)
216         return d->isEmpty();
217     else
218         return true;
219 }
220 
221 /*!
222     Returns whether the coordinate \a coordinate is contained within this geo shape.
223 */
contains(const QGeoCoordinate & coordinate) const224 bool QGeoShape::contains(const QGeoCoordinate &coordinate) const
225 {
226     Q_D(const QGeoShape);
227 
228     if (d)
229         return d->contains(coordinate);
230     else
231         return false;
232 }
233 
234 /*!
235     Returns a QGeoRectangle representing the geographical bounding rectangle of the
236     geo shape, that defines the latitudinal/longitudinal bounds of the geo shape.
237 
238     \since 5.9
239 */
boundingGeoRectangle() const240 QGeoRectangle QGeoShape::boundingGeoRectangle() const
241 {
242     Q_D(const QGeoShape);
243 
244     if (d)
245         return d->boundingGeoRectangle();
246     else
247         return QGeoRectangle();
248 }
249 
250 /*!
251     Returns the coordinate located at the geometric center of the geo shape.
252 
253     \since 5.5
254 */
center() const255 QGeoCoordinate QGeoShape::center() const
256 {
257     Q_D(const QGeoShape);
258 
259     if (d)
260         return d->center();
261     else
262         return QGeoCoordinate();
263 }
264 
265 /*!
266     \deprecated
267 
268     This method used to extend the geo shape to also cover the coordinate \a coordinate.
269 
270     It currently only works for \l QGeoCircle and \l QGeoRectangle, on which the functionality remains,
271     now also accessible through QGeoCircle::extendCircle and QGeoRectangle::extendRectangle.
272 
273     This method should therefore not be called on a generic QGeoShape any longer, as the behavior for
274     other shape types is undefined.
275 
276     \sa QGeoRectangle::extendRectangle, QGeoCircle::extendCircle
277 */
extendShape(const QGeoCoordinate & coordinate)278 void QGeoShape::extendShape(const QGeoCoordinate &coordinate)
279 {
280     Q_D(QGeoShape);
281 
282     if (d)
283         d->extendShape(coordinate);
284 }
285 
286 
287 /*!
288     Returns true if the \a other geo shape is equivalent to this geo shape, otherwise returns
289     false.
290 */
operator ==(const QGeoShape & other) const291 bool QGeoShape::operator==(const QGeoShape &other) const
292 {
293     Q_D(const QGeoShape);
294 
295     if (d == other.d_func())
296         return true;
297 
298     if (!d || !(other.d_func()))
299         return false;
300 
301     return *d == *other.d_func();
302 }
303 
304 /*!
305     Returns true if the \a other geo shape is not equivalent to this geo shape, otherwise returns
306     false.
307 */
operator !=(const QGeoShape & other) const308 bool QGeoShape::operator!=(const QGeoShape &other) const
309 {
310     return !(*this == other);
311 }
312 
313 /*!
314     Assigns \a other to this geo shape and returns a reference to this geo shape.
315 */
operator =(const QGeoShape & other)316 QGeoShape &QGeoShape::operator=(const QGeoShape &other)
317 {
318     if (this == &other)
319         return *this;
320 
321     d_ptr = other.d_ptr;
322     return *this;
323 }
324 
325 /*!
326     Returns a string representation of this geo shape.
327 
328     \since 5.5
329 */
toString() const330 QString QGeoShape::toString() const
331 {
332     return QStringLiteral("QGeoShape(%1)").arg(type());
333 }
334 
335 #ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug dbg,const QGeoShape & shape)336 QDebug operator<<(QDebug dbg, const QGeoShape &shape)
337 {
338     QDebugStateSaver saver(dbg);
339     dbg.nospace() << "QGeoShape(";
340     switch (shape.type()) {
341     case QGeoShape::UnknownType:
342         dbg << "Unknown";
343         break;
344     case QGeoShape::RectangleType:
345         dbg << "Rectangle";
346         break;
347     case QGeoShape::PathType:
348         dbg << "Path";
349         break;
350     case QGeoShape::PolygonType:
351         dbg << "Polygon";
352         break;
353     case QGeoShape::CircleType:
354         dbg << "Circle";
355     }
356 
357     dbg << ')';
358 
359     return dbg;
360 }
361 #endif
362 
363 #ifndef QT_NO_DATASTREAM
operator <<(QDataStream & stream,const QGeoShape & shape)364 QDataStream &operator<<(QDataStream &stream, const QGeoShape &shape)
365 {
366     stream << quint32(shape.type());
367     switch (shape.type()) {
368     case QGeoShape::UnknownType:
369         break;
370     case QGeoShape::RectangleType: {
371         QGeoRectangle r = shape;
372         stream << r.topLeft() << r.bottomRight();
373         break;
374     }
375     case QGeoShape::CircleType: {
376         QGeoCircle c = shape;
377         stream << c.center() << c.radius();
378         break;
379     }
380     case QGeoShape::PathType: {
381         QGeoPath p = shape;
382         stream << p.path().size();
383         for (const auto &c: p.path())
384             stream << c;
385         break;
386     }
387     case QGeoShape::PolygonType: {
388         QGeoPolygon p = shape;
389         stream << p.path().size();
390         for (const auto &c: p.path())
391             stream << c;
392         break;
393     }
394     }
395 
396     return stream;
397 }
398 
operator >>(QDataStream & stream,QGeoShape & shape)399 QDataStream &operator>>(QDataStream &stream, QGeoShape &shape)
400 {
401     quint32 type;
402     stream >> type;
403 
404     switch (type) {
405     case QGeoShape::UnknownType:
406         shape = QGeoShape();
407         break;
408     case QGeoShape::RectangleType: {
409         QGeoCoordinate tl;
410         QGeoCoordinate br;
411         stream >> tl >> br;
412         shape = QGeoRectangle(tl, br);
413         break;
414     }
415     case QGeoShape::CircleType: {
416         QGeoCoordinate c;
417         qreal r;
418         stream >> c >> r;
419         shape = QGeoCircle(c, r);
420         break;
421     }
422     case QGeoShape::PathType: {
423         QList<QGeoCoordinate> l;
424         QGeoCoordinate c;
425         int sz;
426         stream >> sz;
427         for (int i = 0; i < sz; i++) {
428             stream >> c;
429             l.append(c);
430         }
431         shape = QGeoPath(l);
432         break;
433     }
434     case QGeoShape::PolygonType: {
435         QList<QGeoCoordinate> l;
436         QGeoCoordinate c;
437         int sz;
438         stream >> sz;
439         for (int i = 0; i < sz; i++) {
440             stream >> c;
441             l.append(c);
442         }
443         shape = QGeoPolygon(l);
444         break;
445     }
446     }
447 
448     return stream;
449 }
450 #endif
451 
452 QT_END_NAMESPACE
453 
454 #include "moc_qgeoshape.cpp"
455