12#include <QtPositioning/QGeoCircle>
13#include <QtPositioning/QGeoRectangle>
14#include <QtPositioning/QGeoPath>
15#include <QtPositioning/QGeoPolygon>
16#include <QtQuick/QQuickWindow>
17#include <QtQuick/QSGRectangleNode>
18#include <QtQml/qqmlinfo.h>
19#include <QtQuick/private/qquickitem_p.h>
23#define M_PI 3.141592653589793238463
29static qreal sanitizeBearing(qreal bearing)
31 bearing = std::fmod(bearing, qreal(360.0));
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
121
122
123
124
125
127QDeclarativeGeoMap::QDeclarativeGeoMap(QQuickItem *parent)
130 setFlags(QQuickItem::ItemHasContents | QQuickItem::ItemClipsChildrenToShape);
132 m_activeMapType = QGeoMapType(QGeoMapType::NoMap,
137 QByteArrayLiteral(
""),
138 QGeoCameraCapabilities());
139 m_cameraData.setCenter(QGeoCoordinate(51.5073,-0.1277));
140 m_cameraData.setZoomLevel(8.0);
142 m_cameraCapabilities.setTileSize(256);
143 m_cameraCapabilities.setSupportsBearing(
true);
144 m_cameraCapabilities.setSupportsTilting(
true);
145 m_cameraCapabilities.setMinimumZoomLevel(0);
146 m_cameraCapabilities.setMaximumZoomLevel(30);
147 m_cameraCapabilities.setMinimumTilt(0);
148 m_cameraCapabilities.setMaximumTilt(89.5);
149 m_cameraCapabilities.setMinimumFieldOfView(1);
150 m_cameraCapabilities.setMaximumFieldOfView(179);
152 m_minimumZoomLevel = m_cameraCapabilities.minimumZoomLevel();
153 m_maximumZoomLevel = m_cameraCapabilities.maximumZoomLevel();
154 m_minimumTilt = m_cameraCapabilities.minimumTilt();
155 m_maximumTilt = m_cameraCapabilities.maximumTilt();
156 m_minimumFieldOfView = m_cameraCapabilities.minimumFieldOfView();
157 m_maximumFieldOfView = m_cameraCapabilities.maximumFieldOfView();
160QDeclarativeGeoMap::~QDeclarativeGeoMap()
164 m_map->clearMapItems();
169 if (!m_mapViews.isEmpty()) {
170 const auto mapViews = m_mapViews;
171 for (QDeclarativeGeoMapItemView *v : mapViews) {
175 QQuickItem *parent = v->parentItem();
176 QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(parent);
181 removeMapItemView_real(v);
185 if (!m_mapItemGroups.isEmpty()) {
186 const auto mapGroups = m_mapItemGroups;
187 for (QDeclarativeGeoMapItemGroup *g : mapGroups) {
191 QQuickItem *parent =g->parentItem();
192 QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(parent);
197 removeMapItemGroup_real(g);
202 const auto mapItems = m_mapItems;
203 for (
auto mi: mapItems)
204 removeMapItem_real(mi.data());
206 if (m_copyrights.data())
207 delete m_copyrights.data();
208 m_copyrights.clear();
213void QDeclarativeGeoMap::onSupportedMapTypesChanged()
215 m_supportedMapTypes = m_mappingManager->supportedMapTypes();
216 if (m_supportedMapTypes.isEmpty()) {
217 m_map->setActiveMapType(QGeoMapType());
218 }
else if (!m_supportedMapTypes.contains(m_map->activeMapType())) {
219 QGeoMapType type = m_supportedMapTypes.at(0);
220 m_activeMapType = type;
221 m_map->setActiveMapType(type);
224 emit supportedMapTypesChanged();
227void QDeclarativeGeoMap::setError(QGeoServiceProvider::Error error,
const QString &errorString)
229 if (m_error == error && m_errorString == errorString)
232 m_errorString = errorString;
237
238
239
240void QDeclarativeGeoMap::initialize()
243 bool visibleAreaHasChanged =
false;
245 QGeoCoordinate center = m_cameraData.center();
247 setMinimumZoomLevel(m_map->minimumZoom(),
false);
249 double bearing = m_cameraData.bearing();
250 double tilt = m_cameraData.tilt();
251 double fov = m_cameraData.fieldOfView();
252 QGeoCameraData cameraData = m_cameraData;
254 if (!m_cameraCapabilities.supportsBearing() && bearing != 0.0)
255 cameraData.setBearing(0);
257 if (!m_cameraCapabilities.supportsTilting() && tilt != 0.0)
258 cameraData.setTilt(0);
260 m_map->setVisibleArea(m_visibleArea);
261 if (m_map->visibleArea() != m_visibleArea)
262 visibleAreaHasChanged =
true;
264 cameraData.setFieldOfView(qBound(m_cameraCapabilities.minimumFieldOfView(),
266 m_cameraCapabilities.maximumFieldOfView()));
269 m_maximumViewportLatitude = m_map->maximumCenterLatitudeAtZoom(cameraData);
270 m_minimumViewportLatitude = m_map->minimumCenterLatitudeAtZoom(cameraData);
272 center.setLatitude(qBound(m_minimumViewportLatitude, center.latitude(), m_maximumViewportLatitude));
273 cameraData.setCenter(center);
275 connect(m_map.data(), &QGeoMap::cameraDataChanged,
276 this, &QDeclarativeGeoMap::onCameraDataChanged);
277 m_map->setCameraData(cameraData);
282 m_initialized =
true;
284 if (visibleAreaHasChanged)
285 emit visibleAreaChanged();
286 connect(m_map.data(), &QGeoMap::visibleAreaChanged,
this, &QDeclarativeGeoMap::visibleAreaChanged);
288 emit mapReadyChanged(
true);
289 emit visibleRegionChanged();
296
297
298void QDeclarativeGeoMap::pluginReady()
300 QGeoServiceProvider *provider = m_plugin->sharedGeoServiceProvider();
301 m_mappingManager = provider->mappingManager();
303 if (provider->mappingError() != QGeoServiceProvider::NoError) {
304 setError(provider->mappingError(), provider->mappingErrorString());
308 if (!m_mappingManager) {
310 setError(QGeoServiceProvider::NotSupportedError, tr(
"Plugin does not support mapping."));
314 if (!m_mappingManager->isInitialized()) {
315 connect(m_mappingManager, &QGeoMappingManager::initialized,
316 this, &QDeclarativeGeoMap::mappingManagerInitialized);
318 mappingManagerInitialized();
322 disconnect(m_plugin, &QDeclarativeGeoServiceProvider::attached,
323 this, &QDeclarativeGeoMap::pluginReady);
327
328
329void QDeclarativeGeoMap::componentComplete()
331 m_componentCompleted =
true;
333 QQuickItem::componentComplete();
337
338
339
340
341void QDeclarativeGeoMap::populateMap()
343 QSet<QObject *> kids(children().cbegin(), children().cend());
344 const QList<QQuickItem *> quickKids = childItems();
345 for (QQuickItem *ite: quickKids)
348 for (QObject *k : std::as_const(kids)) {
354
355
356void QDeclarativeGeoMap::setupMapView(QDeclarativeGeoMapItemView *view)
362
363
364QSGNode *QDeclarativeGeoMap::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
371 QSGRectangleNode *root =
static_cast<QSGRectangleNode *>(oldNode);
373 root = window()->createRectangleNode();
375 root->setRect(boundingRect());
376 root->setColor(m_color);
378 QSGNode *content = root->childCount() ? root->firstChild() : 0;
379 content = m_map->updateSceneGraph(content, window());
380 if (content && root->childCount() == 0)
381 root->appendChildNode(content);
387
388
389
390
391
392
393
395void QDeclarativeGeoMap::setPlugin(QDeclarativeGeoServiceProvider *plugin)
398 qmlWarning(
this) << QStringLiteral(
"Plugin is a write-once property, and cannot be set again.");
402 emit pluginChanged(m_plugin);
404 if (m_plugin->isAttached()) {
407 connect(m_plugin, &QDeclarativeGeoServiceProvider::attached,
408 this, &QDeclarativeGeoMap::pluginReady);
413
414
415void QDeclarativeGeoMap::onCameraCapabilitiesChanged(
const QGeoCameraCapabilities &oldCameraCapabilities)
417 if (m_map->cameraCapabilities() == oldCameraCapabilities)
420 m_cameraCapabilities = m_map->cameraCapabilities();
422 setMaximumZoomLevel(m_cameraCapabilities.maximumZoomLevel(),
false);
423 setMinimumZoomLevel(m_cameraCapabilities.minimumZoomLevel(),
false);
424 setMinimumTilt(m_cameraCapabilities.minimumTilt(),
false);
425 setMaximumTilt(m_cameraCapabilities.maximumTilt(),
false);
426 setMinimumFieldOfView(m_cameraCapabilities.minimumFieldOfView(),
false);
427 setMaximumFieldOfView(m_cameraCapabilities.maximumFieldOfView(),
false);
431
432
433
434void QDeclarativeGeoMap::mappingManagerInitialized()
436 m_map = m_mappingManager->createMap(
this);
443 for (
const QPointer<QDeclarativeGeoMapItemBase> &item : std::as_const(m_mapItems)) {
445 item->setMap(
this, m_map);
446 m_map->addMapItem(item.data());
451 m_copyrights =
new QDeclarativeGeoMapCopyrightNotice(
this);
452 m_copyrights->setCopyrightsZ(m_maxChildZ + 1);
453 m_copyrights->setCopyrightsVisible(m_copyrightsVisible);
454 m_copyrights->setMapSource(
this);
456 m_supportedMapTypes = m_mappingManager->supportedMapTypes();
458 if (m_activeMapType != QGeoMapType() && m_plugin->name().toLatin1() == m_activeMapType.pluginName()) {
459 m_map->setActiveMapType(m_activeMapType);
461 if (!m_supportedMapTypes.isEmpty()) {
462 m_activeMapType = m_supportedMapTypes.at(0);
463 m_map->setActiveMapType(m_activeMapType);
465 m_activeMapType = QGeoMapType(QGeoMapType::NoMap,
471 QByteArrayLiteral(
""),
472 QGeoCameraCapabilities());
477 onCameraCapabilitiesChanged(m_cameraCapabilities);
483 QString copyrightString;
484 QImage copyrightImage;
485 if (!m_initialized && width() > 0 && height() > 0) {
486 QMetaObject::Connection copyrightStringCatcherConnection =
487 connect(m_map.data(), &QGeoMap::copyrightsChanged,
this,
488 [©rightString](
const QString ©){ copyrightString = copy; });
489 QMetaObject::Connection copyrightImageCatcherConnection =
490 connect(m_map.data(), &QGeoMap::copyrightsImageChanged,
this,
491 [©rightImage](
const QImage ©){ copyrightImage = copy; });
492 m_map->setViewportSize(QSize(width(), height()));
494 QObject::disconnect(copyrightStringCatcherConnection);
495 QObject::disconnect(copyrightImageCatcherConnection);
500 connect(m_map.data(), &QGeoMap::copyrightsImageChanged,
501 this, &QDeclarativeGeoMap::copyrightsImageChanged);
502 connect(m_map.data(), &QGeoMap::copyrightsChanged,
503 this, &QDeclarativeGeoMap::copyrightsChanged);
504 if (!copyrightString.isEmpty())
505 emit m_map->copyrightsChanged(copyrightString);
506 else if (!copyrightImage.isNull())
507 emit m_map->copyrightsImageChanged(copyrightImage);
511 connect(m_window, &QQuickWindow::beforeSynchronizing,
512 this, &QDeclarativeGeoMap::updateItemToWindowTransform, Qt::DirectConnection);
514 connect(m_map.data(), &QGeoMap::sgNodeChanged,
this, &QDeclarativeGeoMap::onSGNodeChanged);
515 connect(m_map.data(), &QGeoMap::cameraCapabilitiesChanged,
516 this, &QDeclarativeGeoMap::onCameraCapabilitiesChanged);
519 m_map->prefetchData();
521 connect(m_mappingManager, &QGeoMappingManager::supportedMapTypesChanged,
522 this, &QDeclarativeGeoMap::onSupportedMapTypesChanged);
523 emit minimumZoomLevelChanged(minimumZoomLevel());
524 emit maximumZoomLevelChanged(maximumZoomLevel());
525 emit supportedMapTypesChanged();
526 emit activeMapTypeChanged();
537
538
539QDeclarativeGeoServiceProvider *QDeclarativeGeoMap::plugin()
const
545
546
547
548
549
550
551void QDeclarativeGeoMap::setMinimumZoomLevel(qreal minimumZoomLevel,
bool userSet)
553 if (minimumZoomLevel >= 0) {
554 qreal oldMinimumZoomLevel =
this->minimumZoomLevel();
557 m_userMinimumZoomLevel = minimumZoomLevel;
559 m_minimumZoomLevel = minimumZoomLevel;
561 if (zoomLevel() < minimumZoomLevel)
562 setZoomLevel(minimumZoomLevel);
564 if (oldMinimumZoomLevel !=
this->minimumZoomLevel())
565 emit minimumZoomLevelChanged(
this->minimumZoomLevel());
570
571
572
573
574
575
576
577
578
579
580
581
583qreal QDeclarativeGeoMap::minimumZoomLevel()
const
585 return qMax(qMin(m_maximumZoomLevel, m_userMinimumZoomLevel), m_minimumZoomLevel);
589
590
591
592
593void QDeclarativeGeoMap::setMaximumZoomLevel(qreal maximumZoomLevel,
bool userSet)
595 if (maximumZoomLevel >= 0) {
596 qreal oldMaximumZoomLevel =
this->maximumZoomLevel();
599 m_userMaximumZoomLevel = maximumZoomLevel;
601 m_maximumZoomLevel = maximumZoomLevel;
603 if (zoomLevel() > maximumZoomLevel)
604 setZoomLevel(maximumZoomLevel);
606 if (oldMaximumZoomLevel !=
this->maximumZoomLevel())
607 emit maximumZoomLevelChanged(
this->maximumZoomLevel());
612
613
614
615
616
617
618
620qreal QDeclarativeGeoMap::maximumZoomLevel()
const
622 return qMin(qMax(m_minimumZoomLevel, m_userMaximumZoomLevel), m_maximumZoomLevel);
626
627
628
629
630
631
632
633
634
635void QDeclarativeGeoMap::setZoomLevel(qreal zoomLevel)
637 return setZoomLevel(zoomLevel, m_cameraCapabilities.overzoomEnabled());
641
642
643
644
645
646
647
648
649
650void QDeclarativeGeoMap::setZoomLevel(qreal zoomLevel,
bool overzoom)
656 QGeoCameraData cameraData = m_map->cameraData();
657 if (cameraData.zoomLevel() == zoomLevel)
660 cameraData.setZoomLevel(qBound<qreal>(overzoom ? m_map->minimumZoom() : m_cameraCapabilities.minimumZoomLevel(),
662 overzoom ? 30 : maximumZoomLevel()));
663 m_maximumViewportLatitude = m_map->maximumCenterLatitudeAtZoom(cameraData);
664 m_minimumViewportLatitude = m_map->minimumCenterLatitudeAtZoom(cameraData);
665 QGeoCoordinate coord = cameraData.center();
666 coord.setLatitude(qBound(m_minimumViewportLatitude, coord.latitude(), m_maximumViewportLatitude));
667 cameraData.setCenter(coord);
668 m_map->setCameraData(cameraData);
670 const bool zlHasChanged = zoomLevel != m_cameraData.zoomLevel();
671 m_cameraData.setZoomLevel(zoomLevel);
673 emit zoomLevelChanged(zoomLevel);
680bool QDeclarativeGeoMap::addMapChild(QObject *child)
683 QDeclarativeGeoMapItemView *mapView = qobject_cast<QDeclarativeGeoMapItemView *>(child);
685 return addMapItemView_real(mapView);
687 QDeclarativeGeoMapItemGroup *itemGroup = qobject_cast<QDeclarativeGeoMapItemGroup *>(child);
689 return addMapItemGroup_real(itemGroup);
691 QDeclarativeGeoMapItemBase *mapItem = qobject_cast<QDeclarativeGeoMapItemBase *>(child);
693 return addMapItem_real(mapItem);
698bool QDeclarativeGeoMap::removeMapChild(QObject *child)
701 QDeclarativeGeoMapItemView *mapView = qobject_cast<QDeclarativeGeoMapItemView *>(child);
703 return removeMapItemView_real(mapView);
705 QDeclarativeGeoMapItemGroup *itemGroup = qobject_cast<QDeclarativeGeoMapItemGroup *>(child);
707 return removeMapItemGroup_real(itemGroup);
709 QDeclarativeGeoMapItemBase *mapItem = qobject_cast<QDeclarativeGeoMapItemBase *>(child);
711 return removeMapItem_real(mapItem);
716bool QDeclarativeGeoMap::isGroupNested(QDeclarativeGeoMapItemGroup *group)
const
718 QObject *parent = group->parent();
722 return qobject_cast<QDeclarativeGeoMapItemGroup *>(parent)
723 || qobject_cast<QDeclarativeGeoMapItemGroup *>(group->parentItem());
726qreal QDeclarativeGeoMap::zoomLevel()
const
729 return m_map->cameraData().zoomLevel();
730 return m_cameraData.zoomLevel();
734
735
736
737
738
739
740
741
742
743void QDeclarativeGeoMap::setBearing(qreal bearing)
745 bearing = sanitizeBearing(bearing);
747 QGeoCameraData cameraData = m_map->cameraData();
748 cameraData.setBearing(bearing);
749 m_map->setCameraData(cameraData);
751 const bool bearingHasChanged = bearing != m_cameraData.bearing();
752 m_cameraData.setBearing(bearing);
753 if (bearingHasChanged) {
754 emit bearingChanged(bearing);
762
763
764
765
766
767
768
769
770
771
772
773void QDeclarativeGeoMap::setBearing(qreal bearing,
const QGeoCoordinate &coordinate)
778 const QGeoCoordinate currentCenter = center();
779 const qreal currentBearing = QDeclarativeGeoMap::bearing();
780 bearing = sanitizeBearing(bearing);
782 if (!coordinate.isValid()
783 || !qIsFinite(bearing)
784 || (coordinate == currentCenter && bearing == currentBearing))
787 if (m_map->capabilities() & QGeoMap::SupportsSetBearing)
788 m_map->setBearing(bearing, coordinate);
791qreal QDeclarativeGeoMap::bearing()
const
794 return m_map->cameraData().bearing();
795 return m_cameraData.bearing();
799
800
801
802
803
804
805
806
807
808
809
810void QDeclarativeGeoMap::setTilt(qreal tilt)
812 tilt = qBound(minimumTilt(), tilt, maximumTilt());
815 QGeoCameraData cameraData = m_map->cameraData();
816 cameraData.setTilt(tilt);
817 m_map->setCameraData(cameraData);
819 const bool tiltHasChanged = tilt != m_cameraData.tilt();
820 m_cameraData.setTilt(tilt);
821 if (tiltHasChanged) {
822 emit tiltChanged(tilt);
829qreal QDeclarativeGeoMap::tilt()
const
832 return m_map->cameraData().tilt();
833 return m_cameraData.tilt();
836void QDeclarativeGeoMap::setMinimumTilt(qreal minimumTilt,
bool userSet)
838 if (minimumTilt >= 0) {
839 qreal oldMinimumTilt =
this->minimumTilt();
842 m_userMinimumTilt = minimumTilt;
844 m_minimumTilt = minimumTilt;
846 if (tilt() < minimumTilt)
847 setTilt(minimumTilt);
849 if (oldMinimumTilt !=
this->minimumTilt())
850 emit minimumTiltChanged(
this->minimumTilt());
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870void QDeclarativeGeoMap::setFieldOfView(qreal fieldOfView)
872 fieldOfView = qBound(minimumFieldOfView(), fieldOfView, maximumFieldOfView());
875 QGeoCameraData cameraData = m_map->cameraData();
876 cameraData.setFieldOfView(fieldOfView);
877 m_map->setCameraData(cameraData);
879 const bool fovChanged = fieldOfView != m_cameraData.fieldOfView();
880 m_cameraData.setFieldOfView(fieldOfView);
882 emit fieldOfViewChanged(fieldOfView);
889qreal QDeclarativeGeoMap::fieldOfView()
const
892 return m_map->cameraData().fieldOfView();
893 return m_cameraData.fieldOfView();
896void QDeclarativeGeoMap::setMinimumFieldOfView(qreal minimumFieldOfView,
bool userSet)
898 if (minimumFieldOfView > 0 && minimumFieldOfView < 180.0) {
899 qreal oldMinimumFoV =
this->minimumFieldOfView();
902 m_userMinimumFieldOfView = minimumFieldOfView;
904 m_minimumFieldOfView = minimumFieldOfView;
906 if (fieldOfView() < minimumFieldOfView)
907 setFieldOfView(minimumFieldOfView);
909 if (oldMinimumFoV !=
this->minimumFieldOfView())
910 emit minimumFieldOfViewChanged(
this->minimumFieldOfView());
915
916
917
918
919
920
921
922
923
924
925
926
927qreal QDeclarativeGeoMap::minimumFieldOfView()
const
929 return qMax(qMin(m_maximumFieldOfView, m_userMinimumFieldOfView), m_minimumFieldOfView);
932void QDeclarativeGeoMap::setMaximumFieldOfView(qreal maximumFieldOfView,
bool userSet)
934 if (maximumFieldOfView > 0 && maximumFieldOfView < 180.0) {
935 qreal oldMaximumFoV =
this->maximumFieldOfView();
937 m_userMaximumFieldOfView = maximumFieldOfView;
939 m_maximumFieldOfView = maximumFieldOfView;
941 if (fieldOfView() > maximumFieldOfView)
942 setFieldOfView(maximumFieldOfView);
944 if (oldMaximumFoV !=
this->maximumFieldOfView())
945 emit maximumFieldOfViewChanged(
this->maximumFieldOfView());
950
951
952
953
954
955
956
957
958
959
960
961
962qreal QDeclarativeGeoMap::maximumFieldOfView()
const
964 return qMin(qMax(m_minimumFieldOfView, m_userMaximumFieldOfView), m_maximumFieldOfView);
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982qreal QDeclarativeGeoMap::minimumTilt()
const
984 return qMax(qMin(m_maximumTilt, m_userMinimumTilt), m_minimumTilt);
987void QDeclarativeGeoMap::setMaximumTilt(qreal maximumTilt,
bool userSet)
989 if (maximumTilt >= 0) {
990 qreal oldMaximumTilt =
this->maximumTilt();
993 m_userMaximumTilt = maximumTilt;
995 m_maximumTilt = maximumTilt;
997 if (tilt() > maximumTilt)
998 setTilt(maximumTilt);
1000 if (oldMaximumTilt !=
this->maximumTilt())
1001 emit maximumTiltChanged(
this->maximumTilt());
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020qreal QDeclarativeGeoMap::maximumTilt()
const
1022 return qMin(qMax(m_minimumTilt, m_userMaximumTilt), m_maximumTilt);
1026
1027
1028
1029
1030
1031
1032
1033void QDeclarativeGeoMap::setCenter(
const QGeoCoordinate ¢er)
1035 if (!center.isValid())
1038 if (m_initialized) {
1039 QGeoCoordinate coord(center);
1040 coord.setLatitude(qBound(m_minimumViewportLatitude, center.latitude(), m_maximumViewportLatitude));
1041 QGeoCameraData cameraData = m_map->cameraData();
1042 cameraData.setCenter(coord);
1043 m_map->setCameraData(cameraData);
1045 const bool centerHasChanged = center != m_cameraData.center();
1046 m_cameraData.setCenter(center);
1047 if (centerHasChanged) {
1048 emit centerChanged(center);
1055QGeoCoordinate QDeclarativeGeoMap::center()
const
1058 return m_map->cameraData().center();
1059 return m_cameraData.center();
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081void QDeclarativeGeoMap::setVisibleRegion(
const QGeoShape &shape)
1083 if (shape.boundingGeoRectangle() == visibleRegion())
1086 m_visibleRegion = shape.boundingGeoRectangle();
1087 if (!m_visibleRegion.isValid()
1088 || (m_visibleRegion.bottomRight().latitude() >= 85.0)
1089 || (m_visibleRegion.topLeft().latitude() <= -85.0)) {
1091 m_visibleRegion = QGeoRectangle();
1092 m_pendingFitViewport =
false;
1093 emit visibleRegionChanged();
1097 if (!m_map || !width() || !height()) {
1098 m_pendingFitViewport =
true;
1099 emit visibleRegionChanged();
1103 fitViewportToGeoShape(m_visibleRegion);
1104 emit visibleRegionChanged();
1107QGeoShape QDeclarativeGeoMap::visibleRegion()
const
1109 if (!m_map || !width() || !height())
1110 return m_visibleRegion;
1112 if (m_map->capabilities() & QGeoMap::SupportsVisibleRegion) {
1113 return m_map->visibleRegion();
1117 QList<QGeoCoordinate> visiblePoly;
1118 visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(0,0),
false);
1119 visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_map->viewportWidth() - 1,
1121 visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_map->viewportWidth() - 1,
1122 m_map->viewportHeight() - 1),
false);
1123 visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(0,
1124 m_map->viewportHeight() - 1),
false);
1126 path.setPath(visiblePoly);
1127 return path.boundingGeoRectangle();
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142void QDeclarativeGeoMap::setCopyrightsVisible(
bool visible)
1144 if (m_copyrightsVisible == visible)
1147 if (!m_copyrights.isNull())
1148 m_copyrights->setCopyrightsVisible(visible);
1150 m_copyrightsVisible = visible;
1151 emit copyrightsVisibleChanged(visible);
1154bool QDeclarativeGeoMap::copyrightsVisible()
const
1156 return m_copyrightsVisible;
1162
1163
1164
1165
1166
1167
1168void QDeclarativeGeoMap::setColor(
const QColor &color)
1170 if (color != m_color) {
1173 emit colorChanged(m_color);
1177QColor QDeclarativeGeoMap::color()
const
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192QRectF QDeclarativeGeoMap::visibleArea()
const
1195 return m_map->visibleArea();
1196 return m_visibleArea;
1199void QDeclarativeGeoMap::setVisibleArea(
const QRectF &visibleArea)
1201 const QRectF oldVisibleArea = QDeclarativeGeoMap::visibleArea();
1202 if (visibleArea == oldVisibleArea)
1205 if (!visibleArea.isValid() && !visibleArea.isEmpty())
1208 if (m_initialized) {
1209 m_map->setVisibleArea(visibleArea);
1210 const QRectF newVisibleArea = QDeclarativeGeoMap::visibleArea();
1211 if (newVisibleArea != oldVisibleArea) {
1213 for (
const QPointer<QDeclarativeGeoMapItemBase> &i: std::as_const(m_mapItems)) {
1215 i->visibleAreaChanged();
1219 m_visibleArea = visibleArea;
1220 const QRectF newVisibleArea = QDeclarativeGeoMap::visibleArea();
1221 if (newVisibleArea != oldVisibleArea)
1222 emit visibleAreaChanged();
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236bool QDeclarativeGeoMap::mapReady()
const
1238 return m_initialized;
1241QMargins QDeclarativeGeoMap::mapMargins()
const
1243 const QRectF va = m_map->visibleArea();
1246 return QMargins( va.x()
1248 , width() - va.width() - va.x()
1249 , height() - va.height() - va.y());
1253
1254
1255
1256
1257
1258
1259QList<QGeoMapType> QDeclarativeGeoMap::supportedMapTypes()
1261 return m_supportedMapTypes;
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282void QDeclarativeGeoMap::alignCoordinateToPoint(
const QGeoCoordinate &coordinate,
const QPointF &point)
1284 if (!m_map || !(m_map->capabilities() & QGeoMap::SupportsAnchoringCoordinate))
1287 if (!coordinate.isValid()
1288 || !qIsFinite(point.x())
1289 || !qIsFinite(point.y()))
1292 m_map->anchorCoordinateToPoint(coordinate, point);
1296
1297
1298
1299
1300
1301
1302
1303QGeoCoordinate QDeclarativeGeoMap::toCoordinate(
const QPointF &position,
bool clipToViewPort)
const
1306 return m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(position), clipToViewPort);
1308 return QGeoCoordinate();
1312
1313
1314
1315
1316
1317
1318
1319QPointF QDeclarativeGeoMap::fromCoordinate(
const QGeoCoordinate &coordinate,
bool clipToViewPort)
const
1322 return m_map->geoProjection().coordinateToItemPosition(coordinate, clipToViewPort).toPointF();
1324 return QPointF(qQNaN(), qQNaN());
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338void QDeclarativeGeoMap::pan(
int dx,
int dy)
1342 if (dx == 0 && dy == 0)
1345 QGeoCoordinate coord = m_map->geoProjection().itemPositionToCoordinate(
1346 QDoubleVector2D(m_map->viewportWidth() / 2 + dx,
1347 m_map->viewportHeight() / 2 + dy));
1353
1354
1355
1356
1357void QDeclarativeGeoMap::prefetchData()
1361 m_map->prefetchData();
1365
1366
1367
1368
1369
1370
1371void QDeclarativeGeoMap::clearData()
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389void QDeclarativeGeoMap::fitViewportToGeoShape(
const QGeoShape &shape, QVariant margins)
1391 QMargins m(10, 10, 10, 10);
1392 switch (margins.typeId()) {
1393 case QMetaType::Int:
1394 case QMetaType::Double: {
1395 const int value =
int(margins.toDouble());
1396 m = QMargins(value, value, value, value);
1403 fitViewportToGeoShape(shape, m);
1406void QDeclarativeGeoMap::fitViewportToGeoShape(
const QGeoShape &shape,
const QMargins &borders)
1408 if (!m_map || !shape.isValid())
1411 if (m_map->geoProjection().projectionType() == QGeoProjection::ProjectionWebMercator) {
1414 const QMargins margins = borders + mapMargins();
1415 const QGeoProjectionWebMercator &p =
static_cast<
const QGeoProjectionWebMercator&>(m_map->geoProjection());
1416 const QPair<QGeoCoordinate, qreal> fitData = p.fitViewportToGeoRectangle(shape.boundingGeoRectangle(),
1418 if (!fitData.first.isValid())
1422 setProperty(
"center", QVariant::fromValue(fitData.first));
1424 if (!qIsFinite(fitData.second))
1426 double newZoom = qMax<
double>(minimumZoomLevel(), fitData.second);
1427 setProperty(
"zoomLevel", QVariant::fromValue(newZoom));
1428 }
else if (m_map->capabilities() & QGeoMap::SupportsFittingViewportToGeoRectangle) {
1430 m_map->fitViewportToGeoRectangle(m_visibleRegion, borders);
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1447QString QDeclarativeGeoMap::errorString()
const
1449 return m_errorString;
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1468QGeoServiceProvider::Error QDeclarativeGeoMap::error()
const
1473QGeoMap *QDeclarativeGeoMap::map()
const
1478void QDeclarativeGeoMap::itemChange(ItemChange change,
const ItemChangeData &value)
1480 if (change == ItemChildAddedChange) {
1481 QQuickItem *child = value.item;
1482 QQuickItem *mapItem = qobject_cast<QDeclarativeGeoMapItemBase *>(child);
1484 mapItem = qobject_cast<QDeclarativeGeoMapItemGroup *>(child);
1487 qreal z = mapItem->z();
1488 if (z > m_maxChildZ) {
1492 m_copyrights->setCopyrightsZ(m_maxChildZ + 1);
1495 }
else if (change == ItemSceneChange) {
1497 disconnect(m_window, &QQuickWindow::beforeSynchronizing,
1498 this, &QDeclarativeGeoMap::updateItemToWindowTransform);
1500 m_window = value.window;
1502 connect(m_window, &QQuickWindow::beforeSynchronizing,
1503 this, &QDeclarativeGeoMap::updateItemToWindowTransform, Qt::DirectConnection);
1506 QQuickItem::itemChange(change, value);
1509void QDeclarativeGeoMap::attachCopyrightNotice(
bool initialVisibility)
1511 if (initialVisibility) {
1512 ++m_copyNoticesVisible;
1514 m_map->setCopyrightVisible(m_copyNoticesVisible > 0);
1518void QDeclarativeGeoMap::detachCopyrightNotice(
bool currentVisibility)
1520 if (currentVisibility) {
1521 --m_copyNoticesVisible;
1523 m_map->setCopyrightVisible(m_copyNoticesVisible > 0);
1527void QDeclarativeGeoMap::onAttachedCopyrightNoticeVisibilityChanged()
1529 QDeclarativeGeoMapCopyrightNotice *copy =
static_cast<QDeclarativeGeoMapCopyrightNotice *>(sender());
1530 m_copyNoticesVisible += (
int(copy->copyrightsVisible()) * 2 - 1);
1532 m_map->setCopyrightVisible(m_copyNoticesVisible > 0);
1535void QDeclarativeGeoMap::onCameraDataChanged(
const QGeoCameraData &cameraData)
1537 bool centerHasChanged = cameraData.center() != m_cameraData.center();
1538 bool bearingHasChanged = cameraData.bearing() != m_cameraData.bearing();
1539 bool tiltHasChanged = cameraData.tilt() != m_cameraData.tilt();
1540 bool fovHasChanged = cameraData.fieldOfView() != m_cameraData.fieldOfView();
1541 bool zoomHasChanged = cameraData.zoomLevel() != m_cameraData.zoomLevel();
1543 m_cameraData = cameraData;
1545 for (
const QPointer<QDeclarativeGeoMapItemBase> &i: std::as_const(m_mapItems)) {
1547 i->baseCameraDataChanged(m_cameraData);
1550 if (centerHasChanged)
1551 emit centerChanged(m_cameraData.center());
1553 emit zoomLevelChanged(m_cameraData.zoomLevel());
1554 if (bearingHasChanged)
1555 emit bearingChanged(m_cameraData.bearing());
1557 emit tiltChanged(m_cameraData.tilt());
1559 emit fieldOfViewChanged(m_cameraData.fieldOfView());
1560 if (centerHasChanged || zoomHasChanged || bearingHasChanged
1561 || tiltHasChanged || fovHasChanged)
1562 emit visibleRegionChanged();
1566
1567
1568
1569
1570
1571
1572
1573
1574
1576QList<QObject *> QDeclarativeGeoMap::mapItems()
1578 QList<QObject *> ret;
1579 for (
const auto &ptr : m_mapItems) {
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1604void QDeclarativeGeoMap::addMapItem(QDeclarativeGeoMapItemBase *item)
1606 if (addMapItem_real(item))
1607 emit mapItemsChanged();
1610bool QDeclarativeGeoMap::addMapItem_real(QDeclarativeGeoMapItemBase *item)
1612 if (!item || item->quickMap())
1615 if (!qobject_cast<QDeclarativeGeoMapItemGroup *>(item->parentItem()))
1616 item->setParentItem(
this);
1617 m_mapItems.append(item);
1619 item->setMap(
this, m_map);
1620 m_map->addMapItem(item);
1626
1627
1628
1629
1630
1631
1632
1633
1634void QDeclarativeGeoMap::removeMapItem(QDeclarativeGeoMapItemBase *ptr)
1636 if (removeMapItem_real(ptr))
1637 emit mapItemsChanged();
1640bool QDeclarativeGeoMap::removeMapItem_real(QDeclarativeGeoMapItemBase *ptr)
1644 QPointer<QDeclarativeGeoMapItemBase> item(ptr);
1645 if (!m_mapItems.contains(item))
1648 m_map->removeMapItem(ptr);
1649 if (item->parentItem() ==
this)
1650 item->setParentItem(0);
1653 m_mapItems.removeOne(item);
1658
1659
1660
1661
1662
1663
1664void QDeclarativeGeoMap::clearMapItems()
1666 if (m_mapItems.isEmpty())
1669 qsizetype removed = 0;
1670 for (qsizetype i = 0; i < m_mapItemGroups.count(); ++i) {
1671 auto item = m_mapItemGroups.at(i);
1673 if (qobject_cast<QDeclarativeGeoMapItemView *>(item))
1677 if (item->parentItem() !=
this)
1680 if (removeMapItemGroup_real(item)) {
1686 while (!m_mapItems.isEmpty())
1687 removed += removeMapItem_real(m_mapItems.first());
1690 emit mapItemsChanged();
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703void QDeclarativeGeoMap::addMapItemGroup(QDeclarativeGeoMapItemGroup *itemGroup)
1705 if (addMapItemGroup_real(itemGroup))
1706 emit mapItemsChanged();
1709bool QDeclarativeGeoMap::addMapItemGroup_real(QDeclarativeGeoMapItemGroup *itemGroup)
1711 if (!itemGroup || itemGroup->quickMap())
1714 itemGroup->setQuickMap(
this);
1716 if (!isGroupNested(itemGroup))
1717 itemGroup->setParentItem(
this);
1719 QPointer<QDeclarativeGeoMapItemGroup> g(itemGroup);
1720 m_mapItemGroups.append(g);
1722 const QList<QQuickItem *> quickKids = itemGroup->childItems();
1724 for (
auto c: quickKids) {
1725 count += addMapChild(c);
1731
1732
1733
1734
1735
1736
1737
1738
1739void QDeclarativeGeoMap::removeMapItemGroup(QDeclarativeGeoMapItemGroup *itemGroup)
1741 if (removeMapItemGroup_real(itemGroup))
1742 emit mapItemsChanged();
1745bool QDeclarativeGeoMap::removeMapItemGroup_real(QDeclarativeGeoMapItemGroup *itemGroup)
1747 if (!itemGroup || itemGroup->quickMap() !=
this)
1750 QPointer<QDeclarativeGeoMapItemGroup> g(itemGroup);
1751 if (!m_mapItemGroups.removeOne(g))
1754 const QList<QQuickItem *> quickKids = itemGroup->childItems();
1756 for (
auto c: quickKids) {
1757 count += removeMapChild(c);
1759 itemGroup->setQuickMap(
nullptr);
1760 if (itemGroup->parentItem() ==
this)
1761 itemGroup->setParentItem(0);
1766
1767
1768
1769
1770
1771
1772
1773
1774void QDeclarativeGeoMap::removeMapItemView(QDeclarativeGeoMapItemView *itemView)
1776 if (removeMapItemView_real(itemView))
1777 emit mapItemsChanged();
1780bool QDeclarativeGeoMap::removeMapItemView_real(QDeclarativeGeoMapItemView *itemView)
1782 if (!itemView || itemView->m_map !=
this)
1785 itemView->removeInstantiatedItems(
false);
1786 itemView->m_map = 0;
1787 m_mapViews.removeOne(itemView);
1788 return removeMapItemGroup_real(itemView);
1791void QDeclarativeGeoMap::updateItemToWindowTransform()
1797 QTransform item2Window = QQuickItemPrivate::get(
this)->itemToWindowTransform();
1798 if (!property(
"layer").isNull() && property(
"layer").value<QObject *>()->property(
"enabled").toBool())
1799 item2Window.reset();
1801 m_map->setItemToWindowTransform(item2Window);
1803 m_sgNodeHasChanged =
false;
1806void QDeclarativeGeoMap::onSGNodeChanged()
1808 m_sgNodeHasChanged =
true;
1813
1814
1815
1816
1817
1818
1819
1820
1821void QDeclarativeGeoMap::addMapItemView(QDeclarativeGeoMapItemView *itemView)
1823 if (addMapItemView_real(itemView))
1824 emit mapItemsChanged();
1827bool QDeclarativeGeoMap::addMapItemView_real(QDeclarativeGeoMapItemView *itemView)
1829 if (!itemView || itemView->m_map)
1832 int count = addMapItemGroup_real(itemView);
1835 m_mapViews.append(itemView);
1836 setupMapView(itemView);
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850void QDeclarativeGeoMap::setActiveMapType(
const QGeoMapType &mapType)
1852 if (m_activeMapType != mapType) {
1854 if (mapType.pluginName() == m_plugin->name().toLatin1()) {
1855 m_map->setActiveMapType(mapType);
1856 m_activeMapType = mapType;
1857 emit activeMapTypeChanged();
1860 m_activeMapType = mapType;
1861 emit activeMapTypeChanged();
1866QGeoMapType QDeclarativeGeoMap::activeMapType()
const
1868 return m_activeMapType;
1872
1873
1874void QDeclarativeGeoMap::geometryChange(
const QRectF &newGeometry,
const QRectF &oldGeometry)
1876 QQuickItem::geometryChange(newGeometry, oldGeometry);
1878 if (!m_map || newGeometry.size().isEmpty())
1881 m_map->setViewportSize(newGeometry.size().toSize());
1883 if (!m_initialized) {
1886 setMinimumZoomLevel(m_map->minimumZoom(),
false);
1889 QGeoCameraData cameraData = m_map->cameraData();
1890 const double maximumCenterLatitudeAtZoom = m_map->maximumCenterLatitudeAtZoom(cameraData);
1891 const double minimumCenterLatitudeAtZoom = m_map->minimumCenterLatitudeAtZoom(cameraData);
1892 if (maximumCenterLatitudeAtZoom != m_maximumViewportLatitude
1893 || minimumCenterLatitudeAtZoom != m_minimumViewportLatitude) {
1894 m_maximumViewportLatitude = maximumCenterLatitudeAtZoom;
1895 m_minimumViewportLatitude = minimumCenterLatitudeAtZoom;
1896 QGeoCoordinate coord = cameraData.center();
1897 coord.setLatitude(qBound(m_minimumViewportLatitude, coord.latitude(), m_maximumViewportLatitude));
1898 cameraData.setCenter(coord);
1899 m_map->setCameraData(cameraData);
1901 if (oldGeometry.size() != newGeometry.size()) {
1903 for (
const QPointer<QDeclarativeGeoMapItemBase> &i: std::as_const(m_mapItems)) {
1905 i->polishAndUpdate();
1911
1912
1913
1914
1915
1916
1917
1918 if (m_pendingFitViewport && width() && height()) {
1919 fitViewportToGeoShape(m_visibleRegion);
1920 m_pendingFitViewport =
false;
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938void QDeclarativeGeoMap::fitViewportToMapItems(
const QVariantList &items)
1941 QList<QPointer<QDeclarativeGeoMapItemBase> > itms;
1942 for (
const QVariant &i: items) {
1943 QDeclarativeGeoMapItemBase *itm = qobject_cast<QDeclarativeGeoMapItemBase *>(i.value<QObject *>());
1947 fitViewportToMapItemsRefine(itms,
true,
false);
1949 fitViewportToMapItemsRefine(m_mapItems,
true,
false);
1954
1955
1956
1957
1958
1959
1960
1961
1962void QDeclarativeGeoMap::fitViewportToVisibleMapItems()
1964 fitViewportToMapItemsRefine(m_mapItems,
true,
true);
1968
1969
1970void QDeclarativeGeoMap::fitViewportToMapItemsRefine(
const QList<QPointer<QDeclarativeGeoMapItemBase> > &mapItems,
1977 if (mapItems.size() == 0)
1980 double minX = qInf();
1981 double maxX = -qInf();
1982 double minY = qInf();
1983 double maxY = -qInf();
1984 double topLeftX = 0;
1985 double topLeftY = 0;
1986 double bottomRightX = 0;
1987 double bottomRightY = 0;
1988 bool haveQuickItem =
false;
1991 qsizetype itemCount = 0;
1992 for (qsizetype i = 0; i < mapItems.count(); ++i) {
1993 if (!mapItems.at(i))
1995 QDeclarativeGeoMapItemBase *item = mapItems.at(i).data();
1996 if (!item || (onlyVisible && (!item->isVisible() || item->mapItemOpacity() <= 0.0)))
2000 QDeclarativeGeoMapQuickItem *quickItem =
2001 qobject_cast<QDeclarativeGeoMapQuickItem*>(item);
2002 if (refine && quickItem) {
2003 haveQuickItem =
true;
2014 if (item->isPolishScheduled())
2015 item->updatePolish();
2017 if (quickItem && quickItem->matrix_ && !quickItem->matrix_->m_matrix.isIdentity()) {
2019 if (quickItem->zoomLevel() == 0.0)
2022 QRectF brect = item->boundingRect();
2023 brect = quickItem->matrix_->m_matrix.mapRect(brect);
2024 QPointF transformedPosition = quickItem->matrix_->m_matrix.map(item->position());
2025 topLeftX = transformedPosition.x();
2026 topLeftY = transformedPosition.y();
2027 bottomRightX = topLeftX + brect.width();
2028 bottomRightY = topLeftY + brect.height();
2030 QGeoRectangle brect = item->geoShape().boundingGeoRectangle();
2031 topLeftX = fromCoordinate(brect.topLeft(),
false).x();
2032 topLeftY = fromCoordinate(brect.topLeft(),
false).y();
2033 bottomRightX = fromCoordinate(brect.bottomRight(),
false).x();
2034 bottomRightY = fromCoordinate(brect.bottomRight(),
false).y();
2037 minX = qMin(minX, topLeftX);
2038 maxX = qMax(maxX, bottomRightX);
2039 minY = qMin(minY, topLeftY);
2040 maxY = qMax(maxY, bottomRightY);
2045 if (itemCount == 0) {
2047 fitViewportToMapItemsRefine(mapItems,
false, onlyVisible);
2050 double bboxWidth = maxX - minX;
2051 double bboxHeight = maxY - minY;
2052 double bboxCenterX = minX + (bboxWidth / 2.0);
2053 double bboxCenterY = minY + (bboxHeight / 2.0);
2056 QGeoCoordinate coordinate;
2057 coordinate = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(bboxCenterX, bboxCenterY),
false);
2058 setProperty(
"center", QVariant::fromValue(coordinate));
2061 double bboxWidthRatio = bboxWidth / (bboxWidth + bboxHeight);
2062 double mapWidthRatio = width() / (width() + height());
2065 if (bboxWidthRatio > mapWidthRatio)
2066 zoomRatio = bboxWidth / width();
2068 zoomRatio = bboxHeight / height();
2070 qreal newZoom = std::log10(zoomRatio) / std::log10(0.5);
2071 newZoom = std::floor(qMax(minimumZoomLevel(), (zoomLevel() + newZoom)));
2072 setProperty(
"zoomLevel", QVariant::fromValue(newZoom));
2077 fitViewportToMapItemsRefine(mapItems,
false, onlyVisible);