Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qgeopolygon.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
"qgeopolygon.h"
6
#
include
"qgeopolygon_p.h"
7
#
include
"qgeopath_p.h"
8
#
include
"qgeocircle.h"
9
10
#
include
"qgeocoordinate.h"
11
#
include
"qnumeric.h"
12
#
include
"qlocationutils_p.h"
13
#
include
"qwebmercator_p.h"
14
15
#
include
"qdoublevector2d_p.h"
16
#
include
"qdoublevector3d_p.h"
17
#
include
"qwebmercator_p.h"
18
19
#
include
<
QtCore
/
qmutex
.
h
>
20
21
#
include
<
mutex
>
22
23
QT_BEGIN_NAMESPACE
24
25
QT_IMPL_METATYPE_EXTERN(
QGeoPolygon
)
26
27
constexpr
int
kMaxInt
=
std
::numeric_limits<
int
>::max();
28
constexpr
auto
kTooManyHoles
= u"The polygon has more holes than fit into an int. "
29
"This can cause errors while querying holes from QML"
;
30
constexpr
auto
kTooManyElements
= u"The polygon has more elements than fit into an int. "
31
"This can cause errors while querying elements from QML"
;
32
33
/*!
34
\class QGeoPolygon
35
\inmodule QtPositioning
36
\ingroup QtPositioning-positioning
37
\since 5.10
38
39
\brief The QGeoPolygon class defines a geographic polygon.
40
41
The polygon is defined by an ordered list of \l QGeoCoordinate objects
42
representing its perimeter.
43
44
Each two adjacent elements in this list are intended to be connected
45
together by the shortest line segment of constant bearing passing
46
through both elements.
47
This type of connection can cross the date line in the longitudinal direction,
48
but never crosses the poles.
49
50
This is relevant for the calculation of the bounding box returned by
51
\l QGeoShape::boundingGeoRectangle() for this shape, which will have the latitude of
52
the top left corner set to the maximum latitude in the path point set.
53
Similarly, the latitude of the bottom right corner will be the minimum latitude
54
in the path point set.
55
56
This class is also accessible in QML as \l[QML]{geoPolygon}.
57
*/
58
59
/*
60
\property QGeoPolygon::path
61
\brief This property holds the list of coordinates for the geo polygon.
62
63
The polygon is both invalid and empty if it contains no coordinate.
64
65
A default constructed QGeoPolygon is therefore invalid.
66
*/
67
68
inline
QGeoPolygonPrivate *QGeoPolygon::d_func()
69
{
70
return
static_cast
<QGeoPolygonPrivate *>(d_ptr.data());
71
}
72
73
inline
const
QGeoPolygonPrivate *QGeoPolygon::d_func()
const
74
{
75
return
static_cast
<
const
QGeoPolygonPrivate *>(d_ptr.constData());
76
}
77
78
/*!
79
Constructs a new, empty geo polygon.
80
*/
81
QGeoPolygon::QGeoPolygon()
82
: QGeoShape(
new
QGeoPolygonPrivate())
83
{
84
}
85
86
/*!
87
Constructs a new geo polygon from the coordinates specified
88
in \a path.
89
*/
90
QGeoPolygon::QGeoPolygon(
const
QList<QGeoCoordinate> &path)
91
: QGeoShape(
new
QGeoPolygonPrivate(path))
92
{
93
}
94
95
/*!
96
Constructs a new geo polygon from the contents of \a other.
97
*/
98
QGeoPolygon::QGeoPolygon(
const
QGeoPolygon &other)
99
: QGeoShape(other)
100
{
101
}
102
103
static
void
calculatePeripheralPoints
(QList<QGeoCoordinate> &path,
104
const
QGeoCircle &circle,
105
int
steps)
106
{
107
const
QGeoCoordinate ¢er = circle.center();
108
const
qreal distance = circle.radius();
109
// Calculate points based on great-circle distance
110
// Calculation is the same as GeoCoordinate's atDistanceAndAzimuth function
111
// but tweaked here for computing multiple points
112
113
// pre-calculations
114
steps = qMax(steps, 3);
115
qreal centerLon = center.longitude();
116
qreal latRad = QLocationUtils::radians(center.latitude());
117
qreal lonRad = QLocationUtils::radians(centerLon);
118
qreal cosLatRad =
std
::cos(latRad);
119
qreal sinLatRad =
std
::sin(latRad);
120
qreal ratio = (distance / QLocationUtils::earthMeanRadius());
121
qreal cosRatio =
std
::cos(ratio);
122
qreal sinRatio =
std
::sin(ratio);
123
qreal sinLatRad_x_cosRatio = sinLatRad * cosRatio;
124
qreal cosLatRad_x_sinRatio = cosLatRad * sinRatio;
125
for
(
int
i = 0; i < steps; ++i) {
126
qreal azimuthRad = 2 *
M_PI
* i / steps;
127
qreal resultLatRad =
std
::asin(sinLatRad_x_cosRatio
128
+ cosLatRad_x_sinRatio *
std
::cos(azimuthRad));
129
qreal resultLonRad = lonRad +
std
::atan2(
std
::sin(azimuthRad) * cosLatRad_x_sinRatio,
130
cosRatio - sinLatRad *
std
::sin(resultLatRad));
131
qreal lat2 = QLocationUtils::degrees(resultLatRad);
132
qreal lon2 = QLocationUtils::wrapLong(QLocationUtils::degrees(resultLonRad));
133
134
path << QGeoCoordinate(lat2, lon2, center.altitude());
135
}
136
}
137
138
/*!
139
Constructs a new geo polygon from the contents of \a other.
140
*/
141
QGeoPolygon::QGeoPolygon(
const
QGeoShape &other)
142
: QGeoShape(other)
143
{
144
if
(type() != QGeoShape::PolygonType) {
145
QGeoPolygonPrivate *poly =
new
QGeoPolygonPrivate();
146
if
(type() == QGeoShape::CircleType) {
147
const
QGeoCircle &circle =
static_cast
<
const
QGeoCircle &>(other);
148
QList<QGeoCoordinate> perimeter;
149
calculatePeripheralPoints(perimeter, circle, 128);
150
poly->setPath(perimeter);
151
}
else
if
(type() == QGeoShape::RectangleType) {
152
const
QGeoRectangle &rect =
static_cast
<
const
QGeoRectangle &>(other);
153
QList<QGeoCoordinate> perimeter;
154
perimeter << rect.topLeft() << rect.topRight()
155
<< rect.bottomRight() << rect.bottomLeft();
156
poly->setPath(perimeter);
157
}
158
d_ptr = poly;
159
}
160
}
161
162
/*!
163
Destroys this polygon.
164
*/
165
QGeoPolygon::~QGeoPolygon() {}
166
167
/*!
168
Assigns \a other to this geo polygon and returns a reference to this geo polygon.
169
*/
170
QGeoPolygon &QGeoPolygon::operator=(
const
QGeoPolygon &other)
171
{
172
QGeoShape::operator=(other);
173
return
*
this
;
174
}
175
176
/*!
177
Sets the perimeter of the polygon based on a list of coordinates \a path.
178
179
\since QtPositioning 5.12
180
*/
181
void
QGeoPolygon::setPerimeter(
const
QList<QGeoCoordinate> &path)
182
{
183
Q_D(QGeoPolygon);
184
return
d->setPath(path);
185
}
186
187
/*!
188
\property QGeoPolygon::perimeter
189
\brief the coordinates of the polygon's perimeter.
190
*/
191
192
/*!
193
Returns all the elements of the polygon's perimeter.
194
195
\since QtPositioning 5.12
196
*/
197
const
QList<QGeoCoordinate> &QGeoPolygon::perimeter()
const
198
{
199
Q_D(
const
QGeoPolygon);
200
return
d->path();
201
}
202
203
/*!
204
Translates this geo polygon by \a degreesLatitude northwards and \a degreesLongitude eastwards.
205
206
Negative values of \a degreesLatitude and \a degreesLongitude correspond to
207
southward and westward translation respectively.
208
*/
209
void
QGeoPolygon::translate(
double
degreesLatitude,
double
degreesLongitude)
210
{
211
Q_D(QGeoPolygon);
212
d->translate(degreesLatitude, degreesLongitude);
213
}
214
215
/*!
216
Returns a copy of this geo polygon translated by \a degreesLatitude northwards and
217
\a degreesLongitude eastwards.
218
219
Negative values of \a degreesLatitude and \a degreesLongitude correspond to
220
southward and westward translation respectively.
221
222
\sa translate()
223
*/
224
QGeoPolygon QGeoPolygon::translated(
double
degreesLatitude,
double
degreesLongitude)
const
225
{
226
QGeoPolygon result(*
this
);
227
result.translate(degreesLatitude, degreesLongitude);
228
return
result;
229
}
230
231
/*!
232
Returns the length of the polygon's perimeter, in meters, from the element \a indexFrom to the element \a indexTo.
233
The length is intended to be the sum of the shortest distances for each pair of adjacent points.
234
*/
235
double
QGeoPolygon::length(qsizetype indexFrom, qsizetype indexTo)
const
236
{
237
Q_D(
const
QGeoPolygon);
238
return
d->length(indexFrom, indexTo);
239
}
240
241
/*!
242
Returns the number of elements in the polygon.
243
244
\since 5.10
245
*/
246
qsizetype QGeoPolygon::size()
const
247
{
248
Q_D(
const
QGeoPolygon);
249
const
qsizetype result = d->size();
250
if
(result > kMaxInt)
251
qWarning() << kTooManyElements;
252
return
result;
253
}
254
255
/*!
256
Appends \a coordinate to the polygon.
257
*/
258
void
QGeoPolygon::addCoordinate(
const
QGeoCoordinate &coordinate)
259
{
260
Q_D(QGeoPolygon);
261
d->addCoordinate(coordinate);
262
if
(d->size() > kMaxInt)
263
qWarning() << kTooManyElements;
264
}
265
266
/*!
267
Inserts \a coordinate at the specified \a index.
268
*/
269
void
QGeoPolygon::insertCoordinate(qsizetype index,
const
QGeoCoordinate &coordinate)
270
{
271
Q_D(QGeoPolygon);
272
d->insertCoordinate(index, coordinate);
273
}
274
275
/*!
276
Replaces the path element at the specified \a index with \a coordinate.
277
*/
278
void
QGeoPolygon::replaceCoordinate(qsizetype index,
const
QGeoCoordinate &coordinate)
279
{
280
Q_D(QGeoPolygon);
281
d->replaceCoordinate(index, coordinate);
282
}
283
284
/*!
285
Returns the coordinate at \a index .
286
*/
287
QGeoCoordinate QGeoPolygon::coordinateAt(qsizetype index)
const
288
{
289
Q_D(
const
QGeoPolygon);
290
return
d->coordinateAt(index);
291
}
292
293
/*!
294
Returns true if the polygon's perimeter contains \a coordinate as one of the elements.
295
*/
296
bool
QGeoPolygon::containsCoordinate(
const
QGeoCoordinate &coordinate)
const
297
{
298
Q_D(
const
QGeoPolygon);
299
return
d->containsCoordinate(coordinate);
300
}
301
302
/*!
303
Removes the last occurrence of \a coordinate from the polygon.
304
*/
305
void
QGeoPolygon::removeCoordinate(
const
QGeoCoordinate &coordinate)
306
{
307
Q_D(QGeoPolygon);
308
d->removeCoordinate(coordinate);
309
}
310
311
/*!
312
Removes element at position \a index from the polygon.
313
*/
314
void
QGeoPolygon::removeCoordinate(qsizetype index)
315
{
316
Q_D(QGeoPolygon);
317
d->removeCoordinate(index);
318
}
319
320
/*!
321
Returns the geo polygon properties as a string.
322
*/
323
QString QGeoPolygon::toString()
const
324
{
325
if
(type() != QGeoShape::PolygonType) {
326
qWarning(
"Not a polygon"
);
327
return
QStringLiteral(
"QGeoPolygon(not a polygon)"
);
328
}
329
330
QString pathString;
331
for
(
const
auto
&p : perimeter())
332
pathString += p.toString() + QLatin1StringView(
"; "
);
333
pathString.chop(2);
334
335
return
QStringLiteral(
"QGeoPolygon([ %1 ])"
).arg(pathString);
336
}
337
338
/*!
339
Sets the \a holePath for a hole inside the polygon. The hole is a
340
QVariant containing a QList<QGeoCoordinate>.
341
342
\since 5.12
343
*/
344
void
QGeoPolygon::addHole(
const
QVariant &holePath)
345
{
346
QList<QGeoCoordinate> qgcHolePath;
347
if
(holePath.canConvert<QVariantList>()) {
348
const
QVariantList qvlHolePath = holePath.toList();
349
for
(
const
QVariant &vertex : qvlHolePath) {
350
if
(vertex.canConvert<QGeoCoordinate>())
351
qgcHolePath << vertex.value<QGeoCoordinate>();
352
}
353
}
354
//ToDo: add QGeoShape support
355
addHole(qgcHolePath);
356
}
357
358
/*!
359
Overloaded method. Sets the \a holePath for a hole inside the polygon. The hole is a QList<QGeoCoordinate>.
360
361
\since 5.12
362
*/
363
void
QGeoPolygon::addHole(
const
QList<QGeoCoordinate> &holePath)
364
{
365
Q_D(QGeoPolygon);
366
d->addHole(holePath);
367
if
(d->holesCount() > kMaxInt)
368
qDebug() << kTooManyHoles;
369
}
370
371
/*!
372
Returns a QVariant containing a QList<QGeoCoordinate>
373
which represents the hole at \a index.
374
375
\since 5.12
376
*/
377
const
QVariantList QGeoPolygon::hole(qsizetype index)
const
378
{
379
Q_D(
const
QGeoPolygon);
380
QVariantList holeCoordinates;
381
for
(
const
QGeoCoordinate &coords: d->holePath(index))
382
holeCoordinates << QVariant::fromValue(coords);
383
return
holeCoordinates;
384
}
385
386
/*!
387
Returns a QList<QGeoCoordinate> which represents the hole at \a index.
388
389
\since 5.12
390
*/
391
const
QList<QGeoCoordinate> QGeoPolygon::holePath(qsizetype index)
const
392
{
393
Q_D(
const
QGeoPolygon);
394
return
d->holePath(index);
395
}
396
397
/*!
398
Removes element at position \a index from the list of holes.
399
400
\since 5.12
401
*/
402
void
QGeoPolygon::removeHole(qsizetype index)
403
{
404
Q_D(QGeoPolygon);
405
return
d->removeHole(index);
406
}
407
408
/*!
409
Returns the number of holes.
410
411
\since 5.12
412
*/
413
qsizetype QGeoPolygon::holesCount()
const
414
{
415
Q_D(
const
QGeoPolygon);
416
const
qsizetype result = d->holesCount();
417
if
(result > kMaxInt)
418
qWarning() << kTooManyHoles;
419
return
result;
420
}
421
422
/*******************************************************************************
423
*
424
* QGeoPathPrivate & friends
425
*
426
*******************************************************************************/
427
428
Q_CONSTINIT
static
QBasicMutex globalPolygonMutex;
429
430
QGeoPolygonPrivate::QGeoPolygonPrivate()
431
: QGeoPathPrivateBase()
432
{
433
type = QGeoShape::PolygonType;
434
}
435
436
QGeoPolygonPrivate::QGeoPolygonPrivate(
const
QList<QGeoCoordinate> &path)
437
: QGeoPathPrivateBase(path)
438
{
439
type = QGeoShape::PolygonType;
440
}
441
442
QGeoPolygonPrivate::QGeoPolygonPrivate(
const
QGeoPolygonPrivate &other)
443
: QGeoPathPrivateBase(other),
444
m_holesList(other.m_holesList)
445
{
446
type = QGeoShape::PolygonType;
447
// Do not copy cached members: they would need mutex locked!
448
// m_clipperDirty is set to true by default, so that it'll properly trigger
449
// re-evaluation when needed.
450
}
451
452
QGeoPolygonPrivate::~QGeoPolygonPrivate() {}
453
454
QGeoShapePrivate *QGeoPolygonPrivate::clone()
const
455
{
456
return
new
QGeoPolygonPrivate(*
this
);
457
}
458
459
bool
QGeoPolygonPrivate::isValid()
const
460
{
461
return
path().size() > 2;
462
}
463
464
bool
QGeoPolygonPrivate::contains(
const
QGeoCoordinate &coordinate)
const
465
{
466
return
polygonContains(coordinate);
467
}
468
469
inline
static
void
translatePoly
( QList<QGeoCoordinate> &m_path,
470
QList<QList<QGeoCoordinate>> &m_holesList,
471
QGeoRectangle &m_bbox,
472
double
degreesLatitude,
473
double
degreesLongitude,
474
double
m_maxLati,
475
double
m_minLati)
476
{
477
if
(degreesLatitude > 0.0)
478
degreesLatitude = qMin(degreesLatitude, 90.0 - m_maxLati);
479
else
480
degreesLatitude = qMax(degreesLatitude, -90.0 - m_minLati);
481
for
(QGeoCoordinate &p: m_path) {
482
p.setLatitude(p.latitude() + degreesLatitude);
483
p.setLongitude(QLocationUtils::wrapLong(p.longitude() + degreesLongitude));
484
}
485
if
(!m_holesList.isEmpty()){
486
for
(QList<QGeoCoordinate> &hole: m_holesList){
487
for
(QGeoCoordinate &holeVertex: hole){
488
holeVertex.setLatitude(holeVertex.latitude() + degreesLatitude);
489
holeVertex.setLongitude(QLocationUtils::wrapLong(holeVertex.longitude() + degreesLongitude));
490
}
491
}
492
}
493
m_bbox.translate(degreesLatitude, degreesLongitude);
494
}
495
496
void
QGeoPolygonPrivate::translate(
double
degreesLatitude,
double
degreesLongitude)
497
{
498
// Need min/maxLati, so update bbox
499
QList<
double
> m_deltaXs;
500
double
m_minX, m_maxX, m_minLati, m_maxLati;
501
computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox);
502
translatePoly(m_path, m_holesList, m_bbox, degreesLatitude, degreesLongitude, m_maxLati, m_minLati);
503
m_bboxDirty.store(
false
, std::memory_order_release);
504
m_clipperDirty.store(
true
, std::memory_order_release);
505
}
506
507
bool
QGeoPolygonPrivate::operator==(
const
QGeoShapePrivate &other)
const
508
{
509
if
(!QGeoPathPrivateBase::operator==(other))
// checks type
510
return
false
;
511
512
const
QGeoPolygonPrivate &otherPolygon =
static_cast
<
const
QGeoPolygonPrivate &>(other);
513
return
m_holesList == otherPolygon.m_holesList;
514
}
515
516
size_t QGeoPolygonPrivate::hash(size_t seed)
const
517
{
518
const
size_t pointsHash = qHashRange(m_path.cbegin(), m_path.cend(), seed);
519
const
size_t holesHash = qHashRange(m_holesList.cbegin(), m_holesList.cend(), seed);
520
return
qHashMulti(seed, pointsHash, holesHash);
521
}
522
523
void
QGeoPolygonPrivate::addHole(
const
QList<QGeoCoordinate> &holePath)
524
{
525
for
(
const
QGeoCoordinate &holeVertex: holePath)
526
if
(!holeVertex.isValid())
527
return
;
528
529
m_holesList << holePath;
530
// ToDo: mark clipper dirty when hole caching gets added
531
}
532
533
const
QList<QGeoCoordinate> QGeoPolygonPrivate::holePath(qsizetype index)
const
534
{
535
return
m_holesList.at(index);
536
}
537
538
void
QGeoPolygonPrivate::removeHole(qsizetype index)
539
{
540
if
(index < 0 || index >= m_holesList.size())
541
return
;
542
543
m_holesList.removeAt(index);
544
// ToDo: mark clipper dirty when hole caching gets added
545
}
546
547
qsizetype QGeoPolygonPrivate::holesCount()
const
548
{
549
return
m_holesList.size();
550
}
551
552
bool
QGeoPolygonPrivate::polygonContains(
const
QGeoCoordinate &coordinate)
const
553
{
554
ensureClipperPathUpdated();
// this one updates bbox too if needed
555
556
QDoubleVector2D coord = QWebMercator::coordToMercator(coordinate);
557
558
if
(coord.x() < m_leftBoundWrapped)
559
coord.setX(coord.x() + 1.0);
560
561
if
(!m_clipperWrapper.pointInPolygon(coord))
562
return
false
;
563
564
// else iterates the holes List checking whether the point is contained inside the holes
565
for
(
const
QList<QGeoCoordinate> &holePath : std::as_const(m_holesList)) {
566
// ToDo: cache these
567
QGeoPolygon holePolygon;
568
holePolygon.setPerimeter(holePath);
569
if
(holePolygon.contains(coordinate))
570
return
false
;
571
}
572
return
true
;
573
}
574
575
void
QGeoPolygonPrivate::markDirty()
576
{
577
QGeoPathPrivateBase::markDirty();
578
m_clipperDirty.store(
true
, std::memory_order_release);
579
}
580
581
void
QGeoPolygonPrivate::ensureClipperPathUpdated()
const
582
{
583
ensureBoundingBoxUpdated();
584
if
(m_clipperDirty.load(std::memory_order_acquire)) {
585
const
std::scoped_lock lock(globalPolygonMutex);
586
if
(m_clipperDirty.load(std::memory_order_acquire)) {
587
m_leftBoundWrapped = QWebMercator::coordToMercator(m_bbox.topLeft()).x();
588
QList<QDoubleVector2D> preservedPath;
589
preservedPath.reserve(m_path.size());
590
for
(
const
QGeoCoordinate &c : std::as_const(m_path)) {
591
QDoubleVector2D crd = QWebMercator::coordToMercator(c);
592
if
(crd.x() < m_leftBoundWrapped)
593
crd.setX(crd.x() + 1.0);
594
preservedPath << crd;
595
}
596
m_clipperWrapper.setPolygon(preservedPath);
597
598
m_clipperDirty.store(
false
, std::memory_order_release);
599
}
600
}
601
}
602
603
QGeoPolygonPrivateEager::QGeoPolygonPrivateEager() : QGeoPolygonPrivate()
604
{
605
m_bboxDirty.store(
false
, std::memory_order_relaxed);
// never dirty on the eager version
606
}
607
608
QGeoPolygonPrivateEager::QGeoPolygonPrivateEager(
const
QList<QGeoCoordinate> &path) : QGeoPolygonPrivate(path)
609
{
610
m_bboxDirty.store(
false
, std::memory_order_relaxed);
// never dirty on the eager version
611
markDirty();
// calculate the cached values
612
}
613
614
QGeoPolygonPrivateEager::QGeoPolygonPrivateEager(
const
QGeoPolygonPrivateEager &other)
615
: QGeoPolygonPrivate(other)
616
{
617
m_bboxDirty.store(
false
, std::memory_order_relaxed);
// never dirty on the eager version
618
markDirty();
// calculate the cached values
619
}
620
621
QGeoPolygonPrivateEager::~QGeoPolygonPrivateEager()
622
{
623
624
}
625
626
QGeoShapePrivate *QGeoPolygonPrivateEager::clone()
const
627
{
628
return
new
QGeoPolygonPrivateEager(*
this
);
629
}
630
631
void
QGeoPolygonPrivateEager::translate(
double
degreesLatitude,
double
degreesLongitude)
632
{
633
translatePoly(m_path, m_holesList, m_bbox, degreesLatitude, degreesLongitude, m_maxLati, m_minLati);
634
m_clipperDirty.store(
true
, std::memory_order_release);
635
}
636
637
void
QGeoPolygonPrivateEager::markDirty()
638
{
639
m_clipperDirty.store(
true
, std::memory_order_release);
640
// do the calculations directly
641
computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox);
642
}
643
644
void
QGeoPolygonPrivateEager::addCoordinate(
const
QGeoCoordinate &coordinate)
645
{
646
if
(!coordinate.isValid())
647
return
;
648
m_path.append(coordinate);
649
m_clipperDirty.store(
true
, std::memory_order_release);
650
updateBoundingBox();
// do not markDirty as it uses computeBoundingBox instead
651
}
652
653
void
QGeoPolygonPrivateEager::updateBoundingBox()
654
{
655
updateBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox);
656
}
657
658
QGeoPolygonEager::QGeoPolygonEager() : QGeoPolygon()
659
{
660
d_ptr =
new
QGeoPolygonPrivateEager;
661
}
662
663
QGeoPolygonEager::QGeoPolygonEager(
const
QList<QGeoCoordinate> &path) : QGeoPolygon()
664
{
665
d_ptr =
new
QGeoPolygonPrivateEager(path);
666
}
667
668
QGeoPolygonEager::QGeoPolygonEager(
const
QGeoPolygon &other) : QGeoPolygon()
669
{
670
// without being able to dynamic_cast the d_ptr, only way to be sure is to reconstruct a new QGeoPolygonPrivateEager
671
d_ptr =
new
QGeoPolygonPrivateEager;
672
setPerimeter(other.perimeter());
673
for
(qsizetype i = 0; i < other.holesCount(); i++)
674
addHole(other.holePath(i));
675
}
676
677
QGeoPolygonEager::QGeoPolygonEager(
const
QGeoShape &other) : QGeoPolygon()
678
{
679
if
(other.type() == QGeoShape::PolygonType)
680
*
this
= QGeoPolygonEager(QGeoPolygon(other));
681
else
682
d_ptr =
new
QGeoPolygonPrivateEager;
683
}
684
685
QGeoPolygonEager::~QGeoPolygonEager()
686
{
687
688
}
689
690
QT_END_NAMESPACE
691
692
#
include
"moc_qgeopolygon_p.cpp"
693
#
include
"moc_qgeopolygon.cpp"
QGeoPolygon
\inmodule QtPositioning
Definition
qgeopolygon.h:17
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
calculatePeripheralPoints
static void calculatePeripheralPoints(QList< QGeoCoordinate > &path, const QGeoCircle &circle, int steps)
Definition
qgeopolygon.cpp:103
translatePoly
static void translatePoly(QList< QGeoCoordinate > &m_path, QList< QList< QGeoCoordinate > > &m_holesList, QGeoRectangle &m_bbox, double degreesLatitude, double degreesLongitude, double m_maxLati, double m_minLati)
Definition
qgeopolygon.cpp:469
kTooManyElements
constexpr auto kTooManyElements
Definition
qgeopolygon.cpp:30
kTooManyHoles
constexpr auto kTooManyHoles
Definition
qgeopolygon.cpp:28
kMaxInt
QT_BEGIN_NAMESPACE constexpr int kMaxInt
Definition
qgeopolygon.cpp:27
M_PI
#define M_PI
Definition
qmath.h:201
qtpositioning
src
positioning
qgeopolygon.cpp
Generated on
for Qt by
1.18.0