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
qgeopath_p.h
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#ifndef QGEOPATH_P_H
6#define QGEOPATH_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtPositioning/private/qpositioningglobal_p.h>
20#include "qgeoshape_p.h"
21#include "qgeocoordinate.h"
23#include <QtPositioning/qgeopath.h>
24#include <QtCore/QList>
25
27
28inline static void computeBBox(const QList<QGeoCoordinate> &m_path, QList<double> &m_deltaXs,
29 double &m_minX, double &m_maxX, double &m_minLati, double &m_maxLati,
30 QGeoRectangle &m_bbox)
31{
32 if (m_path.isEmpty()) {
33 m_deltaXs.clear();
34 m_minX = qInf();
35 m_maxX = -qInf();
36 m_minLati = qInf();
37 m_maxLati = -qInf();
38 m_bbox = QGeoRectangle();
39 return;
40 }
41
42 m_minLati = m_maxLati = m_path.at(0).latitude();
43 qsizetype minId = 0;
44 qsizetype maxId = 0;
45 m_deltaXs.resize(m_path.size());
46 m_deltaXs[0] = m_minX = m_maxX = 0.0;
47
48 for (qsizetype i = 1; i < m_path.size(); i++) {
49 const QGeoCoordinate &geoFrom = m_path.at(i-1);
50 const QGeoCoordinate &geoTo = m_path.at(i);
51 double longiFrom = geoFrom.longitude();
52 double longiTo = geoTo.longitude();
53 double deltaLongi = longiTo - longiFrom;
54 if (qAbs(deltaLongi) > 180.0) {
55 if (longiTo > 0.0)
56 longiTo -= 360.0;
57 else
58 longiTo += 360.0;
59 deltaLongi = longiTo - longiFrom;
60 }
61 m_deltaXs[i] = m_deltaXs[i-1] + deltaLongi;
62 if (m_deltaXs[i] < m_minX) {
63 m_minX = m_deltaXs[i];
64 minId = i;
65 }
66 if (m_deltaXs[i] > m_maxX) {
67 m_maxX = m_deltaXs[i];
68 maxId = i;
69 }
70 if (geoTo.latitude() > m_maxLati)
71 m_maxLati = geoTo.latitude();
72 if (geoTo.latitude() < m_minLati)
73 m_minLati = geoTo.latitude();
74 }
75
76 m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, m_path.at(minId).longitude()),
77 QGeoCoordinate(m_minLati, m_path.at(maxId).longitude()));
78}
79
80inline static void updateBBox(const QList<QGeoCoordinate> &m_path, QList<double> &m_deltaXs,
81 double &m_minX, double &m_maxX, double &m_minLati, double &m_maxLati,
82 QGeoRectangle &m_bbox)
83{
84 if (m_path.isEmpty()) {
85 m_deltaXs.clear();
86 m_minX = qInf();
87 m_maxX = -qInf();
88 m_minLati = qInf();
89 m_maxLati = -qInf();
90 m_bbox = QGeoRectangle();
91 return;
92 } else if (m_path.size() == 1) { // was 0 now is 1
93 m_deltaXs.resize(1);
94 m_deltaXs[0] = m_minX = m_maxX = 0.0;
95 m_minLati = m_maxLati = m_path.at(0).latitude();
96 m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, m_path.at(0).longitude()),
97 QGeoCoordinate(m_minLati, m_path.at(0).longitude()));
98 return;
99 } else if ( m_path.size() != m_deltaXs.size() + 1 ) { // this case should not happen
100 computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox); // something went wrong
101 return;
102 }
103
104 const QGeoCoordinate &geoFrom = m_path.at(m_path.size()-2);
105 const QGeoCoordinate &geoTo = m_path.last();
106 double longiFrom = geoFrom.longitude();
107 double longiTo = geoTo.longitude();
108 double deltaLongi = longiTo - longiFrom;
109 if (qAbs(deltaLongi) > 180.0) {
110 if (longiTo > 0.0)
111 longiTo -= 360.0;
112 else
113 longiTo += 360.0;
114 deltaLongi = longiTo - longiFrom;
115 }
116
117 m_deltaXs.push_back(m_deltaXs.last() + deltaLongi);
118 double currentMinLongi = m_bbox.topLeft().longitude();
119 double currentMaxLongi = m_bbox.bottomRight().longitude();
120 if (m_deltaXs.last() < m_minX) {
121 m_minX = m_deltaXs.last();
122 currentMinLongi = geoTo.longitude();
123 }
124 if (m_deltaXs.last() > m_maxX) {
125 m_maxX = m_deltaXs.last();
126 currentMaxLongi = geoTo.longitude();
127 }
128 if (geoTo.latitude() > m_maxLati)
129 m_maxLati = geoTo.latitude();
130 if (geoTo.latitude() < m_minLati)
131 m_minLati = geoTo.latitude();
132 m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, currentMinLongi),
133 QGeoCoordinate(m_minLati, currentMaxLongi));
134}
135
136// Pure virtual base that can be used in both
137// QGeoPathPrivate and QGeoPolygonPrivate.
138// Does not implement QGeoShape::contains(), because both derived classes
139// have their own implementations. As a result, also does not implement
140// QGeoShape::clone().
141class Q_POSITIONING_EXPORT QGeoPathPrivateBase : public QGeoShapePrivate
142{
143public:
144 QGeoPathPrivateBase();
145 QGeoPathPrivateBase(const QList<QGeoCoordinate> &path);
146 QGeoPathPrivateBase(const QGeoPathPrivateBase &other);
147 ~QGeoPathPrivateBase() override;
148
149// QGeoShape API
150 bool isValid() const override;
151 bool isEmpty() const override;
152 QGeoCoordinate center() const override;
153 bool operator==(const QGeoShapePrivate &other) const override;
154 QGeoRectangle boundingGeoRectangle() const override;
155 size_t hash(size_t seed) const override;
156
157// QGeoPathPrivateBase API
158 virtual const QList<QGeoCoordinate> &path() const;
159 virtual double length(qsizetype indexFrom, qsizetype indexTo) const;
160 virtual qsizetype size() const;
161 virtual QGeoCoordinate coordinateAt(qsizetype index) const;
162 virtual bool containsCoordinate(const QGeoCoordinate &coordinate) const;
163 virtual void translate(double degreesLatitude, double degreesLongitude);
164 virtual void setPath(const QList<QGeoCoordinate> &path);
165 virtual void clearPath();
166 virtual void addCoordinate(const QGeoCoordinate &coordinate);
167 virtual void insertCoordinate(qsizetype index, const QGeoCoordinate &coordinate);
168 virtual void replaceCoordinate(qsizetype index, const QGeoCoordinate &coordinate);
169 virtual void removeCoordinate(const QGeoCoordinate &coordinate);
170 virtual void removeCoordinate(qsizetype index);
171 virtual void markDirty();
172
173 void ensureBoundingBoxUpdated() const;
174
175// data members
176 QList<QGeoCoordinate> m_path;
177 mutable QGeoRectangle m_bbox; // cached
178 mutable std::atomic<bool> m_bboxDirty = true; // default is dirty!
179};
180
181// Lazy by default. Eager, within the module, used only in MapItems/MapObjectsQSG
182class Q_POSITIONING_EXPORT QGeoPathPrivate : public QGeoPathPrivateBase
183{
184public:
185 QGeoPathPrivate();
186 QGeoPathPrivate(const QList<QGeoCoordinate> &path, const qreal width = 0.0);
187 ~QGeoPathPrivate();
188
189// QGeoShape API
190 QGeoShapePrivate *clone() const override;
191 bool operator==(const QGeoShapePrivate &other) const override;
192 bool contains(const QGeoCoordinate &coordinate) const override;
193 size_t hash(size_t seed) const override;
194
195// QGeoPathPrivateBase API: nothing to override
196
197// QGeoPathPrivate API
198 bool lineContains(const QGeoCoordinate &coordinate) const;
199 qreal width() const;
200 void setWidth(const qreal &width);
201
202// data members
203 qreal m_width = 0;
204};
205
206class Q_POSITIONING_EXPORT QGeoPathPrivateEager final : public QGeoPathPrivate
207{
208public:
209 QGeoPathPrivateEager();
210 QGeoPathPrivateEager(const QList<QGeoCoordinate> &path, const qreal width = 0.0);
211 QGeoPathPrivateEager(const QGeoPathPrivateEager &other);
212 ~QGeoPathPrivateEager();
213
214// QGeoShapePrivate API
215 QGeoShapePrivate *clone() const override;
216
217// QGeoPathPrivateBase API
218 void translate(double degreesLatitude, double degreesLongitude) override;
219 void markDirty() override;
220 void addCoordinate(const QGeoCoordinate &coordinate) override;
221
222// *Eager API
223 void updateBoundingBox();
224
225// data members
226 QList<double> m_deltaXs; // longitude deltas from m_path[0]
227 double m_minX = 0; // minimum value inside deltaXs
228 double m_maxX = 0; // maximum value inside deltaXs
229 double m_minLati = 0; // minimum latitude. paths do not wrap around through the poles
230 double m_maxLati = 0; // minimum latitude. paths do not wrap around through the poles
231};
232
233// This is a mean of creating a QGeoPathPrivateEager and injecting it into QGeoPaths via operator=
234class Q_POSITIONING_EXPORT QGeoPathEager : public QGeoPath
235{
236 Q_GADGET
237public:
238
239 QGeoPathEager();
240 QGeoPathEager(const QList<QGeoCoordinate> &path, const qreal &width = 0.0);
241 QGeoPathEager(const QGeoPath &other);
242 QGeoPathEager(const QGeoShape &other);
243 ~QGeoPathEager();
244};
245
246QT_END_NAMESPACE
247
248#endif // QGEOPATH_P_H
\inmodule QtPositioning
Definition qgeopath.h:17
Combined button and popup list for selecting options.
QT_BEGIN_NAMESPACE constexpr auto kWarningString
Definition qgeopath.cpp:24
static void updateBBox(const QList< QGeoCoordinate > &m_path, QList< double > &m_deltaXs, double &m_minX, double &m_maxX, double &m_minLati, double &m_maxLati, QGeoRectangle &m_bbox)
Definition qgeopath_p.h:80
static QT_BEGIN_NAMESPACE void computeBBox(const QList< QGeoCoordinate > &m_path, QList< double > &m_deltaXs, double &m_minX, double &m_maxX, double &m_minLati, double &m_maxLati, QGeoRectangle &m_bbox)
Definition qgeopath_p.h:28