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
120
121
122
123
124
126QDeclarativeGeoMap::QDeclarativeGeoMap(QQuickItem *parent)
129 setFlags(QQuickItem::ItemHasContents | QQuickItem::ItemClipsChildrenToShape);
131 m_activeMapType = QGeoMapType(QGeoMapType::NoMap,
136 QByteArrayLiteral(
""),
137 QGeoCameraCapabilities());
138 m_cameraData.setCenter(QGeoCoordinate(51.5073,-0.1277));
139 m_cameraData.setZoomLevel(8.0);
141 m_cameraCapabilities.setTileSize(256);
142 m_cameraCapabilities.setSupportsBearing(
true);
143 m_cameraCapabilities.setSupportsTilting(
true);
144 m_cameraCapabilities.setMinimumZoomLevel(0);
145 m_cameraCapabilities.setMaximumZoomLevel(30);
146 m_cameraCapabilities.setMinimumTilt(0);
147 m_cameraCapabilities.setMaximumTilt(89.5);
148 m_cameraCapabilities.setMinimumFieldOfView(1);
149 m_cameraCapabilities.setMaximumFieldOfView(179);
151 m_minimumZoomLevel = m_cameraCapabilities.minimumZoomLevel();
152 m_maximumZoomLevel = m_cameraCapabilities.maximumZoomLevel();
153 m_minimumTilt = m_cameraCapabilities.minimumTilt();
154 m_maximumTilt = m_cameraCapabilities.maximumTilt();
155 m_minimumFieldOfView = m_cameraCapabilities.minimumFieldOfView();
156 m_maximumFieldOfView = m_cameraCapabilities.maximumFieldOfView();
159QDeclarativeGeoMap::~QDeclarativeGeoMap()
163 m_map->clearMapItems();
168 if (!m_mapViews.isEmpty()) {
169 const auto mapViews = m_mapViews;
170 for (QDeclarativeGeoMapItemView *v : mapViews) {
174 QQuickItem *parent = v->parentItem();
175 QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(parent);
180 removeMapItemView_real(v);
184 if (!m_mapItemGroups.isEmpty()) {
185 const auto mapGroups = m_mapItemGroups;
186 for (QDeclarativeGeoMapItemGroup *g : mapGroups) {
190 QQuickItem *parent =g->parentItem();
191 QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(parent);
196 removeMapItemGroup_real(g);
201 const auto mapItems = m_mapItems;
202 for (
auto mi: mapItems)
203 removeMapItem_real(mi.data());
205 if (m_copyrights.data())
206 delete m_copyrights.data();
207 m_copyrights.clear();
212void QDeclarativeGeoMap::onSupportedMapTypesChanged()
214 m_supportedMapTypes = m_mappingManager->supportedMapTypes();
215 if (m_supportedMapTypes.isEmpty()) {
216 m_map->setActiveMapType(QGeoMapType());
217 }
else if (!m_supportedMapTypes.contains(m_map->activeMapType())) {
218 QGeoMapType type = m_supportedMapTypes.at(0);
219 m_activeMapType = type;
220 m_map->setActiveMapType(type);
223 emit supportedMapTypesChanged();
226void QDeclarativeGeoMap::setError(QGeoServiceProvider::Error error,
const QString &errorString)
228 if (m_error == error && m_errorString == errorString)
231 m_errorString = errorString;
236
237
238
239void QDeclarativeGeoMap::initialize()
242 bool visibleAreaHasChanged =
false;
244 QGeoCoordinate center = m_cameraData.center();
246 setMinimumZoomLevel(m_map->minimumZoom(),
false);
248 double bearing = m_cameraData.bearing();
249 double tilt = m_cameraData.tilt();
250 double fov = m_cameraData.fieldOfView();
251 QGeoCameraData cameraData = m_cameraData;
253 if (!m_cameraCapabilities.supportsBearing() && bearing != 0.0)
254 cameraData.setBearing(0);
256 if (!m_cameraCapabilities.supportsTilting() && tilt != 0.0)
257 cameraData.setTilt(0);
259 m_map->setVisibleArea(m_visibleArea);
260 if (m_map->visibleArea() != m_visibleArea)
261 visibleAreaHasChanged =
true;
263 cameraData.setFieldOfView(qBound(m_cameraCapabilities.minimumFieldOfView(),
265 m_cameraCapabilities.maximumFieldOfView()));
268 m_maximumViewportLatitude = m_map->maximumCenterLatitudeAtZoom(cameraData);
269 m_minimumViewportLatitude = m_map->minimumCenterLatitudeAtZoom(cameraData);
271 center.setLatitude(qBound(m_minimumViewportLatitude, center.latitude(), m_maximumViewportLatitude));
272 cameraData.setCenter(center);
274 connect(m_map.data(), &QGeoMap::cameraDataChanged,
275 this, &QDeclarativeGeoMap::onCameraDataChanged);
276 m_map->setCameraData(cameraData);
281 m_initialized =
true;
283 if (visibleAreaHasChanged)
284 emit visibleAreaChanged();
285 connect(m_map.data(), &QGeoMap::visibleAreaChanged,
this, &QDeclarativeGeoMap::visibleAreaChanged);
287 emit mapReadyChanged(
true);
288 emit visibleRegionChanged();
295
296
297void QDeclarativeGeoMap::pluginReady()
299 QGeoServiceProvider *provider = m_plugin->sharedGeoServiceProvider();
300 m_mappingManager = provider->mappingManager();
302 if (provider->mappingError() != QGeoServiceProvider::NoError) {
303 setError(provider->mappingError(), provider->mappingErrorString());
307 if (!m_mappingManager) {
309 setError(QGeoServiceProvider::NotSupportedError, tr(
"Plugin does not support mapping."));
313 if (!m_mappingManager->isInitialized()) {
314 connect(m_mappingManager, &QGeoMappingManager::initialized,
315 this, &QDeclarativeGeoMap::mappingManagerInitialized);
317 mappingManagerInitialized();
321 disconnect(m_plugin, &QDeclarativeGeoServiceProvider::attached,
322 this, &QDeclarativeGeoMap::pluginReady);
326
327
328void QDeclarativeGeoMap::componentComplete()
330 m_componentCompleted =
true;
332 QQuickItem::componentComplete();
336
337
338
339
340void QDeclarativeGeoMap::populateMap()
342 QSet<QObject *> kids(children().cbegin(), children().cend());
343 const QList<QQuickItem *> quickKids = childItems();
344 for (QQuickItem *ite: quickKids)
347 for (QObject *k : std::as_const(kids)) {
353
354
355void QDeclarativeGeoMap::setupMapView(QDeclarativeGeoMapItemView *view)
361
362
363QSGNode *QDeclarativeGeoMap::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
370 QSGRectangleNode *root =
static_cast<QSGRectangleNode *>(oldNode);
372 root = window()->createRectangleNode();
374 root->setRect(boundingRect());
375 root->setColor(m_color);
377 QSGNode *content = root->childCount() ? root->firstChild() : 0;
378 content = m_map->updateSceneGraph(content, window());
379 if (content && root->childCount() == 0)
380 root->appendChildNode(content);
386
387
388
389
390
391
392
394void QDeclarativeGeoMap::setPlugin(QDeclarativeGeoServiceProvider *plugin)
397 qmlWarning(
this) << QStringLiteral(
"Plugin is a write-once property, and cannot be set again.");
401 emit pluginChanged(m_plugin);
403 if (m_plugin->isAttached()) {
406 connect(m_plugin, &QDeclarativeGeoServiceProvider::attached,
407 this, &QDeclarativeGeoMap::pluginReady);
412
413
414void QDeclarativeGeoMap::onCameraCapabilitiesChanged(
const QGeoCameraCapabilities &oldCameraCapabilities)
416 if (m_map->cameraCapabilities() == oldCameraCapabilities)
419 m_cameraCapabilities = m_map->cameraCapabilities();
421 setMaximumZoomLevel(m_cameraCapabilities.maximumZoomLevel(),
false);
422 setMinimumZoomLevel(m_cameraCapabilities.minimumZoomLevel(),
false);
423 setMinimumTilt(m_cameraCapabilities.minimumTilt(),
false);
424 setMaximumTilt(m_cameraCapabilities.maximumTilt(),
false);
425 setMinimumFieldOfView(m_cameraCapabilities.minimumFieldOfView(),
false);
426 setMaximumFieldOfView(m_cameraCapabilities.maximumFieldOfView(),
false);
430
431
432
433void QDeclarativeGeoMap::mappingManagerInitialized()
435 m_map = m_mappingManager->createMap(
this);
442 for (
const QPointer<QDeclarativeGeoMapItemBase> &item : std::as_const(m_mapItems)) {
444 item->setMap(
this, m_map);
445 m_map->addMapItem(item.data());
450 m_copyrights =
new QDeclarativeGeoMapCopyrightNotice(
this);
451 m_copyrights->setCopyrightsZ(m_maxChildZ + 1);
452 m_copyrights->setCopyrightsVisible(m_copyrightsVisible);
453 m_copyrights->setMapSource(
this);
455 m_supportedMapTypes = m_mappingManager->supportedMapTypes();
457 if (m_activeMapType != QGeoMapType() && m_plugin->name().toLatin1() == m_activeMapType.pluginName()) {
458 m_map->setActiveMapType(m_activeMapType);
460 if (!m_supportedMapTypes.isEmpty()) {
461 m_activeMapType = m_supportedMapTypes.at(0);
462 m_map->setActiveMapType(m_activeMapType);
464 m_activeMapType = QGeoMapType(QGeoMapType::NoMap,
470 QByteArrayLiteral(
""),
471 QGeoCameraCapabilities());
476 onCameraCapabilitiesChanged(m_cameraCapabilities);
482 QString copyrightString;
483 QImage copyrightImage;
484 if (!m_initialized && width() > 0 && height() > 0) {
485 QMetaObject::Connection copyrightStringCatcherConnection =
486 connect(m_map.data(), &QGeoMap::copyrightsChanged,
this,
487 [©rightString](
const QString ©){ copyrightString = copy; });
488 QMetaObject::Connection copyrightImageCatcherConnection =
489 connect(m_map.data(), &QGeoMap::copyrightsImageChanged,
this,
490 [©rightImage](
const QImage ©){ copyrightImage = copy; });
491 m_map->setViewportSize(QSize(width(), height()));
493 QObject::disconnect(copyrightStringCatcherConnection);
494 QObject::disconnect(copyrightImageCatcherConnection);
499 connect(m_map.data(), &QGeoMap::copyrightsImageChanged,
500 this, &QDeclarativeGeoMap::copyrightsImageChanged);
501 connect(m_map.data(), &QGeoMap::copyrightsChanged,
502 this, &QDeclarativeGeoMap::copyrightsChanged);
503 if (!copyrightString.isEmpty())
504 emit m_map->copyrightsChanged(copyrightString);
505 else if (!copyrightImage.isNull())
506 emit m_map->copyrightsImageChanged(copyrightImage);
510 connect(m_window, &QQuickWindow::beforeSynchronizing,
511 this, &QDeclarativeGeoMap::updateItemToWindowTransform, Qt::DirectConnection);
513 connect(m_map.data(), &QGeoMap::sgNodeChanged,
this, &QDeclarativeGeoMap::onSGNodeChanged);
514 connect(m_map.data(), &QGeoMap::cameraCapabilitiesChanged,
515 this, &QDeclarativeGeoMap::onCameraCapabilitiesChanged);
518 m_map->prefetchData();
520 connect(m_mappingManager, &QGeoMappingManager::supportedMapTypesChanged,
521 this, &QDeclarativeGeoMap::onSupportedMapTypesChanged);
522 emit minimumZoomLevelChanged(minimumZoomLevel());
523 emit maximumZoomLevelChanged(maximumZoomLevel());
524 emit supportedMapTypesChanged();
525 emit activeMapTypeChanged();
536
537
538QDeclarativeGeoServiceProvider *QDeclarativeGeoMap::plugin()
const
544
545
546
547
548
549
550void QDeclarativeGeoMap::setMinimumZoomLevel(qreal minimumZoomLevel,
bool userSet)
552 if (minimumZoomLevel >= 0) {
553 qreal oldMinimumZoomLevel =
this->minimumZoomLevel();
556 m_userMinimumZoomLevel = minimumZoomLevel;
558 m_minimumZoomLevel = minimumZoomLevel;
560 if (zoomLevel() < minimumZoomLevel)
561 setZoomLevel(minimumZoomLevel);
563 if (oldMinimumZoomLevel !=
this->minimumZoomLevel())
564 emit minimumZoomLevelChanged(
this->minimumZoomLevel());
569
570
571
572
573
574
575
576
577
578
579
580
582qreal QDeclarativeGeoMap::minimumZoomLevel()
const
584 return qMax(qMin(m_maximumZoomLevel, m_userMinimumZoomLevel), m_minimumZoomLevel);
588
589
590
591
592void QDeclarativeGeoMap::setMaximumZoomLevel(qreal maximumZoomLevel,
bool userSet)
594 if (maximumZoomLevel >= 0) {
595 qreal oldMaximumZoomLevel =
this->maximumZoomLevel();
598 m_userMaximumZoomLevel = maximumZoomLevel;
600 m_maximumZoomLevel = maximumZoomLevel;
602 if (zoomLevel() > maximumZoomLevel)
603 setZoomLevel(maximumZoomLevel);
605 if (oldMaximumZoomLevel !=
this->maximumZoomLevel())
606 emit maximumZoomLevelChanged(
this->maximumZoomLevel());
611
612
613
614
615
616
617
619qreal QDeclarativeGeoMap::maximumZoomLevel()
const
621 return qMin(qMax(m_minimumZoomLevel, m_userMaximumZoomLevel), m_maximumZoomLevel);
625
626
627
628
629
630
631
632
633
634void QDeclarativeGeoMap::setZoomLevel(qreal zoomLevel)
636 return setZoomLevel(zoomLevel, m_cameraCapabilities.overzoomEnabled());
640
641
642
643
644
645
646
647
648
649void QDeclarativeGeoMap::setZoomLevel(qreal zoomLevel,
bool overzoom)
655 QGeoCameraData cameraData = m_map->cameraData();
656 if (cameraData.zoomLevel() == zoomLevel)
659 cameraData.setZoomLevel(qBound<qreal>(overzoom ? m_map->minimumZoom() : m_cameraCapabilities.minimumZoomLevel(),
661 overzoom ? 30 : maximumZoomLevel()));
662 m_maximumViewportLatitude = m_map->maximumCenterLatitudeAtZoom(cameraData);
663 m_minimumViewportLatitude = m_map->minimumCenterLatitudeAtZoom(cameraData);
664 QGeoCoordinate coord = cameraData.center();
665 coord.setLatitude(qBound(m_minimumViewportLatitude, coord.latitude(), m_maximumViewportLatitude));
666 cameraData.setCenter(coord);
667 m_map->setCameraData(cameraData);
669 const bool zlHasChanged = zoomLevel != m_cameraData.zoomLevel();
670 m_cameraData.setZoomLevel(zoomLevel);
672 emit zoomLevelChanged(zoomLevel);
679bool QDeclarativeGeoMap::addMapChild(QObject *child)
682 QDeclarativeGeoMapItemView *mapView = qobject_cast<QDeclarativeGeoMapItemView *>(child);
684 return addMapItemView_real(mapView);
686 QDeclarativeGeoMapItemGroup *itemGroup = qobject_cast<QDeclarativeGeoMapItemGroup *>(child);
688 return addMapItemGroup_real(itemGroup);
690 QDeclarativeGeoMapItemBase *mapItem = qobject_cast<QDeclarativeGeoMapItemBase *>(child);
692 return addMapItem_real(mapItem);
697bool QDeclarativeGeoMap::removeMapChild(QObject *child)
700 QDeclarativeGeoMapItemView *mapView = qobject_cast<QDeclarativeGeoMapItemView *>(child);
702 return removeMapItemView_real(mapView);
704 QDeclarativeGeoMapItemGroup *itemGroup = qobject_cast<QDeclarativeGeoMapItemGroup *>(child);
706 return removeMapItemGroup_real(itemGroup);
708 QDeclarativeGeoMapItemBase *mapItem = qobject_cast<QDeclarativeGeoMapItemBase *>(child);
710 return removeMapItem_real(mapItem);
715bool QDeclarativeGeoMap::isGroupNested(QDeclarativeGeoMapItemGroup *group)
const
717 QObject *parent = group->parent();
721 return qobject_cast<QDeclarativeGeoMapItemGroup *>(parent)
722 || qobject_cast<QDeclarativeGeoMapItemGroup *>(group->parentItem());
725qreal QDeclarativeGeoMap::zoomLevel()
const
728 return m_map->cameraData().zoomLevel();
729 return m_cameraData.zoomLevel();
733
734
735
736
737
738
739
740
741
742void QDeclarativeGeoMap::setBearing(qreal bearing)
744 bearing = sanitizeBearing(bearing);
746 QGeoCameraData cameraData = m_map->cameraData();
747 cameraData.setBearing(bearing);
748 m_map->setCameraData(cameraData);
750 const bool bearingHasChanged = bearing != m_cameraData.bearing();
751 m_cameraData.setBearing(bearing);
752 if (bearingHasChanged) {
753 emit bearingChanged(bearing);
761
762
763
764
765
766
767
768
769
770
771
772void QDeclarativeGeoMap::setBearing(qreal bearing,
const QGeoCoordinate &coordinate)
777 const QGeoCoordinate currentCenter = center();
778 const qreal currentBearing = QDeclarativeGeoMap::bearing();
779 bearing = sanitizeBearing(bearing);
781 if (!coordinate.isValid()
782 || !qIsFinite(bearing)
783 || (coordinate == currentCenter && bearing == currentBearing))
786 if (m_map->capabilities() & QGeoMap::SupportsSetBearing)
787 m_map->setBearing(bearing, coordinate);
790qreal QDeclarativeGeoMap::bearing()
const
793 return m_map->cameraData().bearing();
794 return m_cameraData.bearing();
798
799
800
801
802
803
804
805
806
807
808
809void QDeclarativeGeoMap::setTilt(qreal tilt)
811 tilt = qBound(minimumTilt(), tilt, maximumTilt());
814 QGeoCameraData cameraData = m_map->cameraData();
815 cameraData.setTilt(tilt);
816 m_map->setCameraData(cameraData);
818 const bool tiltHasChanged = tilt != m_cameraData.tilt();
819 m_cameraData.setTilt(tilt);
820 if (tiltHasChanged) {
821 emit tiltChanged(tilt);
828qreal QDeclarativeGeoMap::tilt()
const
831 return m_map->cameraData().tilt();
832 return m_cameraData.tilt();
835void QDeclarativeGeoMap::setMinimumTilt(qreal minimumTilt,
bool userSet)
837 if (minimumTilt >= 0) {
838 qreal oldMinimumTilt =
this->minimumTilt();
841 m_userMinimumTilt = minimumTilt;
843 m_minimumTilt = minimumTilt;
845 if (tilt() < minimumTilt)
846 setTilt(minimumTilt);
848 if (oldMinimumTilt !=
this->minimumTilt())
849 emit minimumTiltChanged(
this->minimumTilt());
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869void QDeclarativeGeoMap::setFieldOfView(qreal fieldOfView)
871 fieldOfView = qBound(minimumFieldOfView(), fieldOfView, maximumFieldOfView());
874 QGeoCameraData cameraData = m_map->cameraData();
875 cameraData.setFieldOfView(fieldOfView);
876 m_map->setCameraData(cameraData);
878 const bool fovChanged = fieldOfView != m_cameraData.fieldOfView();
879 m_cameraData.setFieldOfView(fieldOfView);
881 emit fieldOfViewChanged(fieldOfView);
888qreal QDeclarativeGeoMap::fieldOfView()
const
891 return m_map->cameraData().fieldOfView();
892 return m_cameraData.fieldOfView();
895void QDeclarativeGeoMap::setMinimumFieldOfView(qreal minimumFieldOfView,
bool userSet)
897 if (minimumFieldOfView > 0 && minimumFieldOfView < 180.0) {
898 qreal oldMinimumFoV =
this->minimumFieldOfView();
901 m_userMinimumFieldOfView = minimumFieldOfView;
903 m_minimumFieldOfView = minimumFieldOfView;
905 if (fieldOfView() < minimumFieldOfView)
906 setFieldOfView(minimumFieldOfView);
908 if (oldMinimumFoV !=
this->minimumFieldOfView())
909 emit minimumFieldOfViewChanged(
this->minimumFieldOfView());
914
915
916
917
918
919
920
921
922
923
924
925
926qreal QDeclarativeGeoMap::minimumFieldOfView()
const
928 return qMax(qMin(m_maximumFieldOfView, m_userMinimumFieldOfView), m_minimumFieldOfView);
931void QDeclarativeGeoMap::setMaximumFieldOfView(qreal maximumFieldOfView,
bool userSet)
933 if (maximumFieldOfView > 0 && maximumFieldOfView < 180.0) {
934 qreal oldMaximumFoV =
this->maximumFieldOfView();
936 m_userMaximumFieldOfView = maximumFieldOfView;
938 m_maximumFieldOfView = maximumFieldOfView;
940 if (fieldOfView() > maximumFieldOfView)
941 setFieldOfView(maximumFieldOfView);
943 if (oldMaximumFoV !=
this->maximumFieldOfView())
944 emit maximumFieldOfViewChanged(
this->maximumFieldOfView());
949
950
951
952
953
954
955
956
957
958
959
960
961qreal QDeclarativeGeoMap::maximumFieldOfView()
const
963 return qMin(qMax(m_minimumFieldOfView, m_userMaximumFieldOfView), m_maximumFieldOfView);
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981qreal QDeclarativeGeoMap::minimumTilt()
const
983 return qMax(qMin(m_maximumTilt, m_userMinimumTilt), m_minimumTilt);
986void QDeclarativeGeoMap::setMaximumTilt(qreal maximumTilt,
bool userSet)
988 if (maximumTilt >= 0) {
989 qreal oldMaximumTilt =
this->maximumTilt();
992 m_userMaximumTilt = maximumTilt;
994 m_maximumTilt = maximumTilt;
996 if (tilt() > maximumTilt)
997 setTilt(maximumTilt);
999 if (oldMaximumTilt !=
this->maximumTilt())
1000 emit maximumTiltChanged(
this->maximumTilt());
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019qreal QDeclarativeGeoMap::maximumTilt()
const
1021 return qMin(qMax(m_minimumTilt, m_userMaximumTilt), m_maximumTilt);
1025
1026
1027
1028
1029
1030
1031
1032void QDeclarativeGeoMap::setCenter(
const QGeoCoordinate ¢er)
1034 if (!center.isValid())
1037 if (m_initialized) {
1038 QGeoCoordinate coord(center);
1039 coord.setLatitude(qBound(m_minimumViewportLatitude, center.latitude(), m_maximumViewportLatitude));
1040 QGeoCameraData cameraData = m_map->cameraData();
1041 cameraData.setCenter(coord);
1042 m_map->setCameraData(cameraData);
1044 const bool centerHasChanged = center != m_cameraData.center();
1045 m_cameraData.setCenter(center);
1046 if (centerHasChanged) {
1047 emit centerChanged(center);
1054QGeoCoordinate QDeclarativeGeoMap::center()
const
1057 return m_map->cameraData().center();
1058 return m_cameraData.center();
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080void QDeclarativeGeoMap::setVisibleRegion(
const QGeoShape &shape)
1082 if (shape.boundingGeoRectangle() == visibleRegion())
1085 m_visibleRegion = shape.boundingGeoRectangle();
1086 if (!m_visibleRegion.isValid()
1087 || (m_visibleRegion.bottomRight().latitude() >= 85.0)
1088 || (m_visibleRegion.topLeft().latitude() <= -85.0)) {
1090 m_visibleRegion = QGeoRectangle();
1091 m_pendingFitViewport =
false;
1092 emit visibleRegionChanged();
1096 if (!m_map || !width() || !height()) {
1097 m_pendingFitViewport =
true;
1098 emit visibleRegionChanged();
1102 fitViewportToGeoShape(m_visibleRegion);
1103 emit visibleRegionChanged();
1106QGeoShape QDeclarativeGeoMap::visibleRegion()
const
1108 if (!m_map || !width() || !height())
1109 return m_visibleRegion;
1111 if (m_map->capabilities() & QGeoMap::SupportsVisibleRegion) {
1112 return m_map->visibleRegion();
1116 QList<QGeoCoordinate> visiblePoly;
1117 visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(0,0),
false);
1118 visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_map->viewportWidth() - 1,
1120 visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_map->viewportWidth() - 1,
1121 m_map->viewportHeight() - 1),
false);
1122 visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(0,
1123 m_map->viewportHeight() - 1),
false);
1125 path.setPath(visiblePoly);
1126 return path.boundingGeoRectangle();
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141void QDeclarativeGeoMap::setCopyrightsVisible(
bool visible)
1143 if (m_copyrightsVisible == visible)
1146 if (!m_copyrights.isNull())
1147 m_copyrights->setCopyrightsVisible(visible);
1149 m_copyrightsVisible = visible;
1150 emit copyrightsVisibleChanged(visible);
1153bool QDeclarativeGeoMap::copyrightsVisible()
const
1155 return m_copyrightsVisible;
1161
1162
1163
1164
1165
1166
1167void QDeclarativeGeoMap::setColor(
const QColor &color)
1169 if (color != m_color) {
1172 emit colorChanged(m_color);
1176QColor QDeclarativeGeoMap::color()
const
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191QRectF QDeclarativeGeoMap::visibleArea()
const
1194 return m_map->visibleArea();
1195 return m_visibleArea;
1198void QDeclarativeGeoMap::setVisibleArea(
const QRectF &visibleArea)
1200 const QRectF oldVisibleArea = QDeclarativeGeoMap::visibleArea();
1201 if (visibleArea == oldVisibleArea)
1204 if (!visibleArea.isValid() && !visibleArea.isEmpty())
1207 if (m_initialized) {
1208 m_map->setVisibleArea(visibleArea);
1209 const QRectF newVisibleArea = QDeclarativeGeoMap::visibleArea();
1210 if (newVisibleArea != oldVisibleArea) {
1212 for (
const QPointer<QDeclarativeGeoMapItemBase> &i: std::as_const(m_mapItems)) {
1214 i->visibleAreaChanged();
1218 m_visibleArea = visibleArea;
1219 const QRectF newVisibleArea = QDeclarativeGeoMap::visibleArea();
1220 if (newVisibleArea != oldVisibleArea)
1221 emit visibleAreaChanged();
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235bool QDeclarativeGeoMap::mapReady()
const
1237 return m_initialized;
1240QMargins QDeclarativeGeoMap::mapMargins()
const
1242 const QRectF va = m_map->visibleArea();
1245 return QMargins( va.x()
1247 , width() - va.width() - va.x()
1248 , height() - va.height() - va.y());
1252
1253
1254
1255
1256
1257
1258QList<QGeoMapType> QDeclarativeGeoMap::supportedMapTypes()
1260 return m_supportedMapTypes;
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281void QDeclarativeGeoMap::alignCoordinateToPoint(
const QGeoCoordinate &coordinate,
const QPointF &point)
1283 if (!m_map || !(m_map->capabilities() & QGeoMap::SupportsAnchoringCoordinate))
1286 if (!coordinate.isValid()
1287 || !qIsFinite(point.x())
1288 || !qIsFinite(point.y()))
1291 m_map->anchorCoordinateToPoint(coordinate, point);
1295
1296
1297
1298
1299
1300
1301
1302QGeoCoordinate QDeclarativeGeoMap::toCoordinate(
const QPointF &position,
bool clipToViewPort)
const
1305 return m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(position), clipToViewPort);
1307 return QGeoCoordinate();
1311
1312
1313
1314
1315
1316
1317
1318QPointF QDeclarativeGeoMap::fromCoordinate(
const QGeoCoordinate &coordinate,
bool clipToViewPort)
const
1321 return m_map->geoProjection().coordinateToItemPosition(coordinate, clipToViewPort).toPointF();
1323 return QPointF(qQNaN(), qQNaN());
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337void QDeclarativeGeoMap::pan(
int dx,
int dy)
1341 if (dx == 0 && dy == 0)
1344 QGeoCoordinate coord = m_map->geoProjection().itemPositionToCoordinate(
1345 QDoubleVector2D(m_map->viewportWidth() / 2 + dx,
1346 m_map->viewportHeight() / 2 + dy));
1352
1353
1354
1355
1356void QDeclarativeGeoMap::prefetchData()
1360 m_map->prefetchData();
1364
1365
1366
1367
1368
1369
1370void QDeclarativeGeoMap::clearData()
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388void QDeclarativeGeoMap::fitViewportToGeoShape(
const QGeoShape &shape, QVariant margins)
1390 QMargins m(10, 10, 10, 10);
1391 switch (margins.typeId()) {
1392 case QMetaType::Int:
1393 case QMetaType::Double: {
1394 const int value =
int(margins.toDouble());
1395 m = QMargins(value, value, value, value);
1402 fitViewportToGeoShape(shape, m);
1405void QDeclarativeGeoMap::fitViewportToGeoShape(
const QGeoShape &shape,
const QMargins &borders)
1407 if (!m_map || !shape.isValid())
1410 if (m_map->geoProjection().projectionType() == QGeoProjection::ProjectionWebMercator) {
1413 const QMargins margins = borders + mapMargins();
1414 const QGeoProjectionWebMercator &p =
static_cast<
const QGeoProjectionWebMercator&>(m_map->geoProjection());
1415 const QPair<QGeoCoordinate, qreal> fitData = p.fitViewportToGeoRectangle(shape.boundingGeoRectangle(),
1417 if (!fitData.first.isValid())
1421 setProperty(
"center", QVariant::fromValue(fitData.first));
1423 if (!qIsFinite(fitData.second))
1425 double newZoom = qMax<
double>(minimumZoomLevel(), fitData.second);
1426 setProperty(
"zoomLevel", QVariant::fromValue(newZoom));
1427 }
else if (m_map->capabilities() & QGeoMap::SupportsFittingViewportToGeoRectangle) {
1429 m_map->fitViewportToGeoRectangle(m_visibleRegion, borders);
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1446QString QDeclarativeGeoMap::errorString()
const
1448 return m_errorString;
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1467QGeoServiceProvider::Error QDeclarativeGeoMap::error()
const
1472QGeoMap *QDeclarativeGeoMap::map()
const
1477void QDeclarativeGeoMap::itemChange(ItemChange change,
const ItemChangeData &value)
1479 if (change == ItemChildAddedChange) {
1480 QQuickItem *child = value.item;
1481 QQuickItem *mapItem = qobject_cast<QDeclarativeGeoMapItemBase *>(child);
1483 mapItem = qobject_cast<QDeclarativeGeoMapItemGroup *>(child);
1486 qreal z = mapItem->z();
1487 if (z > m_maxChildZ) {
1491 m_copyrights->setCopyrightsZ(m_maxChildZ + 1);
1494 }
else if (change == ItemSceneChange) {
1496 disconnect(m_window, &QQuickWindow::beforeSynchronizing,
1497 this, &QDeclarativeGeoMap::updateItemToWindowTransform);
1499 m_window = value.window;
1501 connect(m_window, &QQuickWindow::beforeSynchronizing,
1502 this, &QDeclarativeGeoMap::updateItemToWindowTransform, Qt::DirectConnection);
1505 QQuickItem::itemChange(change, value);
1508void QDeclarativeGeoMap::attachCopyrightNotice(
bool initialVisibility)
1510 if (initialVisibility) {
1511 ++m_copyNoticesVisible;
1513 m_map->setCopyrightVisible(m_copyNoticesVisible > 0);
1517void QDeclarativeGeoMap::detachCopyrightNotice(
bool currentVisibility)
1519 if (currentVisibility) {
1520 --m_copyNoticesVisible;
1522 m_map->setCopyrightVisible(m_copyNoticesVisible > 0);
1526void QDeclarativeGeoMap::onAttachedCopyrightNoticeVisibilityChanged()
1528 QDeclarativeGeoMapCopyrightNotice *copy =
static_cast<QDeclarativeGeoMapCopyrightNotice *>(sender());
1529 m_copyNoticesVisible += (
int(copy->copyrightsVisible()) * 2 - 1);
1531 m_map->setCopyrightVisible(m_copyNoticesVisible > 0);
1534void QDeclarativeGeoMap::onCameraDataChanged(
const QGeoCameraData &cameraData)
1536 bool centerHasChanged = cameraData.center() != m_cameraData.center();
1537 bool bearingHasChanged = cameraData.bearing() != m_cameraData.bearing();
1538 bool tiltHasChanged = cameraData.tilt() != m_cameraData.tilt();
1539 bool fovHasChanged = cameraData.fieldOfView() != m_cameraData.fieldOfView();
1540 bool zoomHasChanged = cameraData.zoomLevel() != m_cameraData.zoomLevel();
1542 m_cameraData = cameraData;
1544 for (
const QPointer<QDeclarativeGeoMapItemBase> &i: std::as_const(m_mapItems)) {
1546 i->baseCameraDataChanged(m_cameraData);
1549 if (centerHasChanged)
1550 emit centerChanged(m_cameraData.center());
1552 emit zoomLevelChanged(m_cameraData.zoomLevel());
1553 if (bearingHasChanged)
1554 emit bearingChanged(m_cameraData.bearing());
1556 emit tiltChanged(m_cameraData.tilt());
1558 emit fieldOfViewChanged(m_cameraData.fieldOfView());
1559 if (centerHasChanged || zoomHasChanged || bearingHasChanged
1560 || tiltHasChanged || fovHasChanged)
1561 emit visibleRegionChanged();
1565
1566
1567
1568
1569
1570
1571
1572
1573
1575QList<QObject *> QDeclarativeGeoMap::mapItems()
1577 QList<QObject *> ret;
1578 for (
const auto &ptr : m_mapItems) {
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1603void QDeclarativeGeoMap::addMapItem(QDeclarativeGeoMapItemBase *item)
1605 if (addMapItem_real(item))
1606 emit mapItemsChanged();
1609bool QDeclarativeGeoMap::addMapItem_real(QDeclarativeGeoMapItemBase *item)
1611 if (!item || item->quickMap())
1614 if (!qobject_cast<QDeclarativeGeoMapItemGroup *>(item->parentItem()))
1615 item->setParentItem(
this);
1616 m_mapItems.append(item);
1618 item->setMap(
this, m_map);
1619 m_map->addMapItem(item);
1625
1626
1627
1628
1629
1630
1631
1632
1633void QDeclarativeGeoMap::removeMapItem(QDeclarativeGeoMapItemBase *ptr)
1635 if (removeMapItem_real(ptr))
1636 emit mapItemsChanged();
1639bool QDeclarativeGeoMap::removeMapItem_real(QDeclarativeGeoMapItemBase *ptr)
1643 QPointer<QDeclarativeGeoMapItemBase> item(ptr);
1644 if (!m_mapItems.contains(item))
1647 m_map->removeMapItem(ptr);
1648 if (item->parentItem() ==
this)
1649 item->setParentItem(0);
1652 m_mapItems.removeOne(item);
1657
1658
1659
1660
1661
1662
1663void QDeclarativeGeoMap::clearMapItems()
1665 if (m_mapItems.isEmpty())
1668 qsizetype removed = 0;
1669 for (qsizetype i = 0; i < m_mapItemGroups.count(); ++i) {
1670 auto item = m_mapItemGroups.at(i);
1672 if (qobject_cast<QDeclarativeGeoMapItemView *>(item))
1676 if (item->parentItem() !=
this)
1679 if (removeMapItemGroup_real(item)) {
1685 while (!m_mapItems.isEmpty())
1686 removed += removeMapItem_real(m_mapItems.first());
1689 emit mapItemsChanged();
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702void QDeclarativeGeoMap::addMapItemGroup(QDeclarativeGeoMapItemGroup *itemGroup)
1704 if (addMapItemGroup_real(itemGroup))
1705 emit mapItemsChanged();
1708bool QDeclarativeGeoMap::addMapItemGroup_real(QDeclarativeGeoMapItemGroup *itemGroup)
1710 if (!itemGroup || itemGroup->quickMap())
1713 itemGroup->setQuickMap(
this);
1715 if (!isGroupNested(itemGroup))
1716 itemGroup->setParentItem(
this);
1718 QPointer<QDeclarativeGeoMapItemGroup> g(itemGroup);
1719 m_mapItemGroups.append(g);
1721 const QList<QQuickItem *> quickKids = itemGroup->childItems();
1723 for (
auto c: quickKids) {
1724 count += addMapChild(c);
1730
1731
1732
1733
1734
1735
1736
1737
1738void QDeclarativeGeoMap::removeMapItemGroup(QDeclarativeGeoMapItemGroup *itemGroup)
1740 if (removeMapItemGroup_real(itemGroup))
1741 emit mapItemsChanged();
1744bool QDeclarativeGeoMap::removeMapItemGroup_real(QDeclarativeGeoMapItemGroup *itemGroup)
1746 if (!itemGroup || itemGroup->quickMap() !=
this)
1749 QPointer<QDeclarativeGeoMapItemGroup> g(itemGroup);
1750 if (!m_mapItemGroups.removeOne(g))
1753 const QList<QQuickItem *> quickKids = itemGroup->childItems();
1755 for (
auto c: quickKids) {
1756 count += removeMapChild(c);
1758 itemGroup->setQuickMap(
nullptr);
1759 if (itemGroup->parentItem() ==
this)
1760 itemGroup->setParentItem(0);
1765
1766
1767
1768
1769
1770
1771
1772
1773void QDeclarativeGeoMap::removeMapItemView(QDeclarativeGeoMapItemView *itemView)
1775 if (removeMapItemView_real(itemView))
1776 emit mapItemsChanged();
1779bool QDeclarativeGeoMap::removeMapItemView_real(QDeclarativeGeoMapItemView *itemView)
1781 if (!itemView || itemView->m_map !=
this)
1784 itemView->removeInstantiatedItems(
false);
1785 itemView->m_map = 0;
1786 m_mapViews.removeOne(itemView);
1787 return removeMapItemGroup_real(itemView);
1790void QDeclarativeGeoMap::updateItemToWindowTransform()
1796 QTransform item2Window = QQuickItemPrivate::get(
this)->itemToWindowTransform();
1797 if (!property(
"layer").isNull() && property(
"layer").value<QObject *>()->property(
"enabled").toBool())
1798 item2Window.reset();
1800 m_map->setItemToWindowTransform(item2Window);
1802 m_sgNodeHasChanged =
false;
1805void QDeclarativeGeoMap::onSGNodeChanged()
1807 m_sgNodeHasChanged =
true;
1812
1813
1814
1815
1816
1817
1818
1819
1820void QDeclarativeGeoMap::addMapItemView(QDeclarativeGeoMapItemView *itemView)
1822 if (addMapItemView_real(itemView))
1823 emit mapItemsChanged();
1826bool QDeclarativeGeoMap::addMapItemView_real(QDeclarativeGeoMapItemView *itemView)
1828 if (!itemView || itemView->m_map)
1831 int count = addMapItemGroup_real(itemView);
1834 m_mapViews.append(itemView);
1835 setupMapView(itemView);
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849void QDeclarativeGeoMap::setActiveMapType(
const QGeoMapType &mapType)
1851 if (m_activeMapType != mapType) {
1853 if (mapType.pluginName() == m_plugin->name().toLatin1()) {
1854 m_map->setActiveMapType(mapType);
1855 m_activeMapType = mapType;
1856 emit activeMapTypeChanged();
1859 m_activeMapType = mapType;
1860 emit activeMapTypeChanged();
1865QGeoMapType QDeclarativeGeoMap::activeMapType()
const
1867 return m_activeMapType;
1871
1872
1873void QDeclarativeGeoMap::geometryChange(
const QRectF &newGeometry,
const QRectF &oldGeometry)
1875 QQuickItem::geometryChange(newGeometry, oldGeometry);
1877 if (!m_map || newGeometry.size().isEmpty())
1880 m_map->setViewportSize(newGeometry.size().toSize());
1882 if (!m_initialized) {
1885 setMinimumZoomLevel(m_map->minimumZoom(),
false);
1888 QGeoCameraData cameraData = m_map->cameraData();
1889 const double maximumCenterLatitudeAtZoom = m_map->maximumCenterLatitudeAtZoom(cameraData);
1890 const double minimumCenterLatitudeAtZoom = m_map->minimumCenterLatitudeAtZoom(cameraData);
1891 if (maximumCenterLatitudeAtZoom != m_maximumViewportLatitude
1892 || minimumCenterLatitudeAtZoom != m_minimumViewportLatitude) {
1893 m_maximumViewportLatitude = maximumCenterLatitudeAtZoom;
1894 m_minimumViewportLatitude = minimumCenterLatitudeAtZoom;
1895 QGeoCoordinate coord = cameraData.center();
1896 coord.setLatitude(qBound(m_minimumViewportLatitude, coord.latitude(), m_maximumViewportLatitude));
1897 cameraData.setCenter(coord);
1898 m_map->setCameraData(cameraData);
1900 if (oldGeometry.size() != newGeometry.size()) {
1902 for (
const QPointer<QDeclarativeGeoMapItemBase> &i: std::as_const(m_mapItems)) {
1904 i->polishAndUpdate();
1910
1911
1912
1913
1914
1915
1916
1917 if (m_pendingFitViewport && width() && height()) {
1918 fitViewportToGeoShape(m_visibleRegion);
1919 m_pendingFitViewport =
false;
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937void QDeclarativeGeoMap::fitViewportToMapItems(
const QVariantList &items)
1940 QList<QPointer<QDeclarativeGeoMapItemBase> > itms;
1941 for (
const QVariant &i: items) {
1942 QDeclarativeGeoMapItemBase *itm = qobject_cast<QDeclarativeGeoMapItemBase *>(i.value<QObject *>());
1946 fitViewportToMapItemsRefine(itms,
true,
false);
1948 fitViewportToMapItemsRefine(m_mapItems,
true,
false);
1953
1954
1955
1956
1957
1958
1959
1960
1961void QDeclarativeGeoMap::fitViewportToVisibleMapItems()
1963 fitViewportToMapItemsRefine(m_mapItems,
true,
true);
1967
1968
1969void QDeclarativeGeoMap::fitViewportToMapItemsRefine(
const QList<QPointer<QDeclarativeGeoMapItemBase> > &mapItems,
1976 if (mapItems.size() == 0)
1979 double minX = qInf();
1980 double maxX = -qInf();
1981 double minY = qInf();
1982 double maxY = -qInf();
1983 double topLeftX = 0;
1984 double topLeftY = 0;
1985 double bottomRightX = 0;
1986 double bottomRightY = 0;
1987 bool haveQuickItem =
false;
1990 qsizetype itemCount = 0;
1991 for (qsizetype i = 0; i < mapItems.count(); ++i) {
1992 if (!mapItems.at(i))
1994 QDeclarativeGeoMapItemBase *item = mapItems.at(i).data();
1995 if (!item || (onlyVisible && (!item->isVisible() || item->mapItemOpacity() <= 0.0)))
1999 QDeclarativeGeoMapQuickItem *quickItem =
2000 qobject_cast<QDeclarativeGeoMapQuickItem*>(item);
2001 if (refine && quickItem) {
2002 haveQuickItem =
true;
2013 if (item->isPolishScheduled())
2014 item->updatePolish();
2016 if (quickItem && quickItem->matrix_ && !quickItem->matrix_->m_matrix.isIdentity()) {
2018 if (quickItem->zoomLevel() == 0.0)
2021 QRectF brect = item->boundingRect();
2022 brect = quickItem->matrix_->m_matrix.mapRect(brect);
2023 QPointF transformedPosition = quickItem->matrix_->m_matrix.map(item->position());
2024 topLeftX = transformedPosition.x();
2025 topLeftY = transformedPosition.y();
2026 bottomRightX = topLeftX + brect.width();
2027 bottomRightY = topLeftY + brect.height();
2029 QGeoRectangle brect = item->geoShape().boundingGeoRectangle();
2030 topLeftX = fromCoordinate(brect.topLeft(),
false).x();
2031 topLeftY = fromCoordinate(brect.topLeft(),
false).y();
2032 bottomRightX = fromCoordinate(brect.bottomRight(),
false).x();
2033 bottomRightY = fromCoordinate(brect.bottomRight(),
false).y();
2036 minX = qMin(minX, topLeftX);
2037 maxX = qMax(maxX, bottomRightX);
2038 minY = qMin(minY, topLeftY);
2039 maxY = qMax(maxY, bottomRightY);
2044 if (itemCount == 0) {
2046 fitViewportToMapItemsRefine(mapItems,
false, onlyVisible);
2049 double bboxWidth = maxX - minX;
2050 double bboxHeight = maxY - minY;
2051 double bboxCenterX = minX + (bboxWidth / 2.0);
2052 double bboxCenterY = minY + (bboxHeight / 2.0);
2055 QGeoCoordinate coordinate;
2056 coordinate = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(bboxCenterX, bboxCenterY),
false);
2057 setProperty(
"center", QVariant::fromValue(coordinate));
2060 double bboxWidthRatio = bboxWidth / (bboxWidth + bboxHeight);
2061 double mapWidthRatio = width() / (width() + height());
2064 if (bboxWidthRatio > mapWidthRatio)
2065 zoomRatio = bboxWidth / width();
2067 zoomRatio = bboxHeight / height();
2069 qreal newZoom = std::log10(zoomRatio) / std::log10(0.5);
2070 newZoom = std::floor(qMax(minimumZoomLevel(), (zoomLevel() + newZoom)));
2071 setProperty(
"zoomLevel", QVariant::fromValue(newZoom));
2076 fitViewportToMapItemsRefine(mapItems,
false, onlyVisible);