17QT_IMPL_METATYPE_EXTERN(QGeoCoordinate)
19static const double qgeocoordinate_EARTH_MEAN_RADIUS = 6371.0072;
22QGeoCoordinatePrivate::QGeoCoordinatePrivate():
28QGeoCoordinatePrivate::QGeoCoordinatePrivate(
const QGeoCoordinatePrivate &other)
35QGeoCoordinatePrivate::~QGeoCoordinatePrivate()
39QGeoMercatorCoordinatePrivate::QGeoMercatorCoordinatePrivate():
40 QGeoCoordinatePrivate(),
45QGeoMercatorCoordinatePrivate::QGeoMercatorCoordinatePrivate(
const QGeoMercatorCoordinatePrivate &other)
46 : QGeoCoordinatePrivate(other),
47 m_mercatorX(other.m_mercatorX),
48 m_mercatorY(other.m_mercatorY)
51QGeoMercatorCoordinatePrivate::~QGeoMercatorCoordinatePrivate()
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
81
82
83
84
85
86
87
90
91
92
93
94
95
96
97
98
99
100
101
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
140
141
142
143
144
145
146
147
148
149
152
153
154
155
156
157
158
159
160
161
162
165
166
167
168QGeoCoordinate::QGeoCoordinate()
169 : d(
new QGeoCoordinatePrivate)
174
175
176
177
178
179
180
181
182QGeoCoordinate::QGeoCoordinate(
double latitude,
double longitude)
183 : d(
new QGeoCoordinatePrivate)
185 if (QLocationUtils::isValidLat(latitude) && QLocationUtils::isValidLong(longitude)) {
192
193
194
195
196
197
198
199
200
201
202
203QGeoCoordinate::QGeoCoordinate(
double latitude,
double longitude,
double altitude)
204 : d(
new QGeoCoordinatePrivate)
206 if (QLocationUtils::isValidLat(latitude) && QLocationUtils::isValidLong(longitude)) {
214
215
216QGeoCoordinate::QGeoCoordinate(
const QGeoCoordinate &other)
221
222
223
224
225
226
227
228
229
232
233
234QGeoCoordinate &QGeoCoordinate::operator=(
const QGeoCoordinate &other)
244
245
246
247
248
249
250
251
252
253
256
257
258QGeoCoordinate::~QGeoCoordinate()
262QT_DEFINE_QSDP_SPECIALIZATION_DTOR(QGeoCoordinatePrivate)
265
266
267
268
269
270
271
272
275
276
277
278
279
280
283
284
285bool QGeoCoordinate::isValid()
const
287 CoordinateType t = type();
288 return t == Coordinate2D || t == Coordinate3D;
292
293
294QGeoCoordinate::CoordinateType QGeoCoordinate::type()
const
296 if (QLocationUtils::isValidLat(d->lat)
297 && QLocationUtils::isValidLong(d->lng)) {
302 return InvalidCoordinate;
307
308
309
310
311
312
313
314
315double QGeoCoordinate::latitude()
const
321
322
323
324
325
326
327
328void QGeoCoordinate::setLatitude(
double latitude)
334
335
336
337
338
339
340
341
342double QGeoCoordinate::longitude()
const
348
349
350
351
352
353
354
355void QGeoCoordinate::setLongitude(
double longitude)
361
362
363
364
365
366
367double QGeoCoordinate::altitude()
const
373
374
375
376
377void QGeoCoordinate::setAltitude(
double altitude)
383
384
385
386
387
388
389
390
391
392
393qreal QGeoCoordinate::distanceTo(
const QGeoCoordinate &other)
const
395 if (type() == QGeoCoordinate::InvalidCoordinate
396 || other.type() == QGeoCoordinate::InvalidCoordinate) {
401 double dlat = qDegreesToRadians(other.d->lat - d->lat);
402 double dlon = qDegreesToRadians(other.d->lng - d->lng);
403 double haversine_dlat = sin(dlat / 2.0);
404 haversine_dlat *= haversine_dlat;
405 double haversine_dlon = sin(dlon / 2.0);
406 haversine_dlon *= haversine_dlon;
407 double y = haversine_dlat
408 + cos(qDegreesToRadians(d->lat))
409 * cos(qDegreesToRadians(other.d->lat))
411 double x = 2 * asin(sqrt(y));
412 return qreal(x * qgeocoordinate_EARTH_MEAN_RADIUS * 1000);
416
417
418
419
420
421
422
423
424
425
426qreal QGeoCoordinate::azimuthTo(
const QGeoCoordinate &other)
const
428 if (type() == QGeoCoordinate::InvalidCoordinate
429 || other.type() == QGeoCoordinate::InvalidCoordinate) {
433 double dlon = qDegreesToRadians(other.d->lng - d->lng);
434 double lat1Rad = qDegreesToRadians(d->lat);
435 double lat2Rad = qDegreesToRadians(other.d->lat);
437 double y = sin(dlon) * cos(lat2Rad);
438 double x = cos(lat1Rad) * sin(lat2Rad) - sin(lat1Rad) * cos(lat2Rad) * cos(dlon);
440 double azimuth = qRadiansToDegrees(atan2(y, x)) + 360.0;
442 double fraction = modf(azimuth, &whole);
443 return qreal((
int(whole + 360) % 360) + fraction);
446void QGeoCoordinatePrivate::atDistanceAndAzimuth(
const QGeoCoordinate &coord,
447 qreal distance, qreal azimuth,
448 double *lon,
double *lat)
450 double latRad = qDegreesToRadians(coord.d->lat);
451 double lonRad = qDegreesToRadians(coord.d->lng);
452 double cosLatRad = cos(latRad);
453 double sinLatRad = sin(latRad);
455 double azimuthRad = qDegreesToRadians(azimuth);
457 double ratio = (distance / (qgeocoordinate_EARTH_MEAN_RADIUS * 1000.0));
458 double cosRatio = cos(ratio);
459 double sinRatio = sin(ratio);
461 double resultLatRad = asin(sinLatRad * cosRatio
462 + cosLatRad * sinRatio * cos(azimuthRad));
463 double resultLonRad = lonRad + atan2(sin(azimuthRad) * sinRatio * cosLatRad,
464 cosRatio - sinLatRad * sin(resultLatRad));
466 *lat = qRadiansToDegrees(resultLatRad);
467 *lon = qRadiansToDegrees(resultLonRad);
471
472
473
474
475
476
477
478
479
480QGeoCoordinate QGeoCoordinate::atDistanceAndAzimuth(qreal distance, qreal azimuth, qreal distanceUp)
const
483 return QGeoCoordinate();
485 double resultLon, resultLat;
486 QGeoCoordinatePrivate::atDistanceAndAzimuth(*
this, distance, azimuth,
487 &resultLon, &resultLat);
488 double resultAlt = d->alt + distanceUp;
489 return QGeoCoordinate(resultLat, QLocationUtils::wrapLong(resultLon), resultAlt);
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527QString QGeoCoordinate::toString(CoordinateFormat format)
const
529 if (type() == QGeoCoordinate::InvalidCoordinate)
535 double absLat = qAbs(d->lat);
536 double absLng = qAbs(d->lng);
537 QChar symbol(0x00B0);
541 case DegreesWithHemisphere: {
542 latStr = QString::number(absLat,
'f', 5) + symbol;
543 longStr = QString::number(absLng,
'f', 5) + symbol;
547 case DegreesMinutesWithHemisphere: {
548 double latMin = (absLat -
int(absLat)) * 60;
549 double lngMin = (absLng -
int(absLng)) * 60;
556 if (latMin > 59.9995) {
560 if (lngMin > 59.9995) {
565 latStr = QString::fromLatin1(
"%1%2 %3'")
566 .arg(QString::number(
int(absLat)))
568 .arg(QString::number(latMin,
'f', 3));
569 longStr = QString::fromLatin1(
"%1%2 %3'")
570 .arg(QString::number(
int(absLng)))
572 .arg(QString::number(lngMin,
'f', 3));
575 case DegreesMinutesSeconds:
576 case DegreesMinutesSecondsWithHemisphere: {
577 double latMin = (absLat -
int(absLat)) * 60;
578 double lngMin = (absLng -
int(absLng)) * 60;
579 double latSec = (latMin -
int(latMin)) * 60;
580 double lngSec = (lngMin -
int(lngMin)) * 60;
587 if (latSec >= 59.95) {
593 if (qRound(latMin) >= 60) {
598 if (lngSec >= 59.95) {
601 if (qRound(lngMin) >= 60) {
607 latStr = QString::fromLatin1(
"%1%2 %3' %4\"")
608 .arg(QString::number(
int(absLat)))
610 .arg(QString::number(
int(latMin)))
611 .arg(QString::number(latSec,
'f', 1));
612 longStr = QString::fromLatin1(
"%1%2 %3' %4\"")
613 .arg(QString::number(
int(absLng)))
615 .arg(QString::number(
int(lngMin)))
616 .arg(QString::number(lngSec,
'f', 1));
625 case DegreesMinutesSeconds: {
627 latStr.insert(0, QStringLiteral(
"-"));
629 longStr.insert(0, QStringLiteral(
"-"));
632 case DegreesWithHemisphere:
633 case DegreesMinutesWithHemisphere:
634 case DegreesMinutesSecondsWithHemisphere: {
636 latStr.append(QString::fromLatin1(
" S"));
638 latStr.append(QString::fromLatin1(
" N"));
640 longStr.append(QString::fromLatin1(
" W"));
642 longStr.append(QString::fromLatin1(
" E"));
648 return QString::fromLatin1(
"%1, %2").arg(latStr, longStr);
649 return QString::fromLatin1(
"%1, %2, %3m").arg(latStr, longStr, QString::number(d->alt));
652bool QGeoCoordinate::equals(
const QGeoCoordinate &lhs,
const QGeoCoordinate &rhs)
654 bool latEqual = (qIsNaN(lhs.d->lat) && qIsNaN(rhs.d->lat))
655 || qFuzzyCompare(lhs.d->lat, rhs.d->lat);
656 bool lngEqual = (qIsNaN(lhs.d->lng) && qIsNaN(rhs.d->lng))
657 || qFuzzyCompare(lhs.d->lng, rhs.d->lng);
658 bool altEqual = (qIsNaN(lhs.d->alt) && qIsNaN(rhs.d->alt))
659 || qFuzzyCompare(lhs.d->alt, rhs.d->alt);
661 if (!qIsNaN(lhs.d->lat) && ((lhs.d->lat == 90.0) || (lhs.d->lat == -90.0)))
664 return (latEqual && lngEqual && altEqual);
667QGeoCoordinate::QGeoCoordinate(QGeoCoordinatePrivate &dd):
672#ifndef QT_NO_DEBUG_STREAM
673QDebug QGeoCoordinate::debugStreaming(QDebug dbg,
const QGeoCoordinate &coord)
675 QDebugStateSaver saver(dbg);
676 double lat = coord.latitude();
677 double lng = coord.longitude();
679 QTextStreamManipulator tsm = qSetRealNumberPrecision(11);
681 dbg.nospace() <<
"QGeoCoordinate(";
691 if (coord.type() == QGeoCoordinate::Coordinate3D) {
693 dbg << coord.altitude();
700#ifndef QT_NO_DATASTREAM
702
703
704
705
706
707
709QDataStream &QGeoCoordinate::dataStreamOut(QDataStream &stream,
const QGeoCoordinate &coordinate)
711 stream << coordinate.latitude();
712 stream << coordinate.longitude();
713 stream << coordinate.altitude();
718#ifndef QT_NO_DATASTREAM
720
721
722
723
724
725
726
728QDataStream &QGeoCoordinate::dataStreamIn(QDataStream &stream, QGeoCoordinate &coordinate)
732 coordinate.setLatitude(value);
734 coordinate.setLongitude(value);
736 coordinate.setAltitude(value);
742
743
744
745
748 QtPrivate::QHashCombine hash;
750 if (coordinate.latitude() != 90.0 && coordinate.latitude() != -90.0)
751 seed = hash(seed, coordinate.longitude());
752 seed = hash(seed, coordinate.latitude());
753 seed = hash(seed, coordinate.altitude());
759#include "moc_qgeocoordinate.cpp"
Combined button and popup list for selecting options.
constexpr size_t qHash(const QSize &s, size_t seed=0) noexcept