13#include <QtPositioning/QGeoCircle>
14#include <QtPositioning/QGeoRectangle>
15#include <QtPositioning/QGeoPath>
16#include <QtPositioning/QGeoPolygon>
17#include <QtQuick/QQuickWindow>
18#include <QtQuick/QSGRectangleNode>
19#include <QtQml/qqmlinfo.h>
20#include <QtQuick/private/qquickitem_p.h>
24#define M_PI 3.141592653589793238463
30static qreal sanitizeBearing(qreal bearing)
32 bearing = std::fmod(bearing, qreal(360.0));
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
119
122
123
124
125
126
128QDeclarativeGeoMap::QDeclarativeGeoMap(QQuickItem *parent)
131 setFlags(QQuickItem::ItemHasContents | QQuickItem::ItemClipsChildrenToShape);
133 m_activeMapType = QGeoMapType(QGeoMapType::NoMap,
138 QByteArrayLiteral(
""),
139 QGeoCameraCapabilities());
140 m_cameraData.setCenter(QGeoCoordinate(51.5073,-0.1277));
141 m_cameraData.setZoomLevel(8.0);
143 m_cameraCapabilities.setTileSize(256);
144 m_cameraCapabilities.setSupportsBearing(
true);
145 m_cameraCapabilities.setSupportsTilting(
true);
146 m_cameraCapabilities.setMinimumZoomLevel(0);
147 m_cameraCapabilities.setMaximumZoomLevel(30);
148 m_cameraCapabilities.setMinimumTilt(0);
149 m_cameraCapabilities.setMaximumTilt(89.5);
150 m_cameraCapabilities.setMinimumFieldOfView(1);
151 m_cameraCapabilities.setMaximumFieldOfView(179);
153 m_minimumZoomLevel = m_cameraCapabilities.minimumZoomLevel();
154 m_maximumZoomLevel = m_cameraCapabilities.maximumZoomLevel();
155 m_minimumTilt = m_cameraCapabilities.minimumTilt();
156 m_maximumTilt = m_cameraCapabilities.maximumTilt();
157 m_minimumFieldOfView = m_cameraCapabilities.minimumFieldOfView();
158 m_maximumFieldOfView = m_cameraCapabilities.maximumFieldOfView();
161QDeclarativeGeoMap::~QDeclarativeGeoMap()
165 m_map->clearMapItems();
170 if (!m_mapViews.isEmpty()) {
171 const auto mapViews = m_mapViews;
172 for (QDeclarativeGeoMapItemView *v : mapViews) {
176 QQuickItem *parent = v->parentItem();
177 QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(parent);
182 removeMapItemView_real(v);
186 if (!m_mapItemGroups.isEmpty()) {
187 const auto mapGroups = m_mapItemGroups;
188 for (QDeclarativeGeoMapItemGroup *g : mapGroups) {
192 QQuickItem *parent =g->parentItem();
193 QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(parent);
198 removeMapItemGroup_real(g);
203 const auto mapItems = m_mapItems;
204 for (
auto mi: mapItems)
205 removeMapItem_real(mi.data());
207 if (m_copyrights.data())
208 delete m_copyrights.data();
209 m_copyrights.clear();
214void QDeclarativeGeoMap::onSupportedMapTypesChanged()
216 m_supportedMapTypes = m_mappingManager->supportedMapTypes();
217 if (m_supportedMapTypes.isEmpty()) {
218 m_map->setActiveMapType(QGeoMapType());
219 }
else if (!m_supportedMapTypes.contains(m_map->activeMapType())) {
220 QGeoMapType type = m_supportedMapTypes.at(0);
221 m_activeMapType = type;
222 m_map->setActiveMapType(type);
225 emit supportedMapTypesChanged();
228void QDeclarativeGeoMap::setError(QGeoServiceProvider::Error error,
const QString &errorString)
230 if (m_error == error && m_errorString == errorString)
233 m_errorString = errorString;
238
239
240
241void QDeclarativeGeoMap::initialize()
244 bool visibleAreaHasChanged =
false;
246 QGeoCoordinate center = m_cameraData.center();
248 setMinimumZoomLevel(m_map->minimumZoom(),
false);
250 double bearing = m_cameraData.bearing();
251 double tilt = m_cameraData.tilt();
252 double fov = m_cameraData.fieldOfView();
253 QGeoCameraData cameraData = m_cameraData;
255 if (!m_cameraCapabilities.supportsBearing() && bearing != 0.0)
256 cameraData.setBearing(0);
258 if (!m_cameraCapabilities.supportsTilting() && tilt != 0.0)
259 cameraData.setTilt(0);
261 m_map->setVisibleArea(m_visibleArea);
262 if (m_map->visibleArea() != m_visibleArea)
263 visibleAreaHasChanged =
true;
265 cameraData.setFieldOfView(qBound(m_cameraCapabilities.minimumFieldOfView(),
267 m_cameraCapabilities.maximumFieldOfView()));
270 m_maximumViewportLatitude = m_map->maximumCenterLatitudeAtZoom(cameraData);
271 m_minimumViewportLatitude = m_map->minimumCenterLatitudeAtZoom(cameraData);
273 center.setLatitude(qBound(m_minimumViewportLatitude, center.latitude(), m_maximumViewportLatitude));
274 cameraData.setCenter(center);
276 connect(m_map.data(), &QGeoMap::cameraDataChanged,
277 this, &QDeclarativeGeoMap::onCameraDataChanged);
278 m_map->setCameraData(cameraData);
283 m_initialized =
true;
285 if (visibleAreaHasChanged)
286 emit visibleAreaChanged();
287 connect(m_map.data(), &QGeoMap::visibleAreaChanged,
this, &QDeclarativeGeoMap::visibleAreaChanged);
289 emit mapReadyChanged(
true);
290 emit visibleRegionChanged();
297
298
299void QDeclarativeGeoMap::pluginReady()
301 QGeoServiceProvider *provider = m_plugin->sharedGeoServiceProvider();
302 m_mappingManager = provider->mappingManager();
304 if (provider->mappingError() != QGeoServiceProvider::NoError) {
305 setError(provider->mappingError(), provider->mappingErrorString());
309 if (!m_mappingManager) {
311 setError(QGeoServiceProvider::NotSupportedError, tr(
"Plugin does not support mapping."));
315 if (!m_mappingManager->isInitialized()) {
316 connect(m_mappingManager, &QGeoMappingManager::initialized,
317 this, &QDeclarativeGeoMap::mappingManagerInitialized);
319 mappingManagerInitialized();
323 disconnect(m_plugin, &QDeclarativeGeoServiceProvider::attached,
324 this, &QDeclarativeGeoMap::pluginReady);
328
329
330void QDeclarativeGeoMap::componentComplete()
332 m_componentCompleted =
true;
334 QQuickItem::componentComplete();
338
339
340
341
342void QDeclarativeGeoMap::populateMap()
344 QSet<QObject *> kids(children().cbegin(), children().cend());
345 const QList<QQuickItem *> quickKids = childItems();
346 for (QQuickItem *ite: quickKids)
349 for (QObject *k : std::as_const(kids)) {
355
356
357void QDeclarativeGeoMap::setupMapView(QDeclarativeGeoMapItemView *view)
363
364
365QSGNode *QDeclarativeGeoMap::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
372 QSGRectangleNode *root =
static_cast<QSGRectangleNode *>(oldNode);
374 root = window()->createRectangleNode();
376 root->setRect(boundingRect());
377 root->setColor(m_color);
379 QSGNode *content = root->childCount() ? root->firstChild() : 0;
380 content = m_map->updateSceneGraph(content, window());
381 if (content && root->childCount() == 0)
382 root->appendChildNode(content);
388
389
390
391
392
393
394
396void QDeclarativeGeoMap::setPlugin(QDeclarativeGeoServiceProvider *plugin)
399 qmlWarning(
this) << QStringLiteral(
"Plugin is a write-once property, and cannot be set again.");
403 emit pluginChanged(m_plugin);
405 if (m_plugin->isAttached()) {
408 connect(m_plugin, &QDeclarativeGeoServiceProvider::attached,
409 this, &QDeclarativeGeoMap::pluginReady);
414
415
416void QDeclarativeGeoMap::onCameraCapabilitiesChanged(
const QGeoCameraCapabilities &oldCameraCapabilities)
418 if (m_map->cameraCapabilities() == oldCameraCapabilities)
421 m_cameraCapabilities = m_map->cameraCapabilities();
423 setMaximumZoomLevel(m_cameraCapabilities.maximumZoomLevel(),
false);
424 setMinimumZoomLevel(m_cameraCapabilities.minimumZoomLevel(),
false);
425 setMinimumTilt(m_cameraCapabilities.minimumTilt(),
false);
426 setMaximumTilt(m_cameraCapabilities.maximumTilt(),
false);
427 setMinimumFieldOfView(m_cameraCapabilities.minimumFieldOfView(),
false);
428 setMaximumFieldOfView(m_cameraCapabilities.maximumFieldOfView(),
false);
432
433
434
435void QDeclarativeGeoMap::mappingManagerInitialized()
437 m_map = m_mappingManager->createMap(
this);
444 for (
const QPointer<QDeclarativeGeoMapItemBase> &item : std::as_const(m_mapItems)) {
446 item->setMap(
this, m_map);
447 m_map->addMapItem(item.data());
452 m_copyrights =
new QDeclarativeGeoMapCopyrightNotice(
this);
453 m_copyrights->setCopyrightsZ(m_maxChildZ + 1);
454 m_copyrights->setCopyrightsVisible(m_copyrightsVisible);
455 m_copyrights->setMapSource(
this);
457 m_supportedMapTypes = m_mappingManager->supportedMapTypes();
459 if (m_activeMapType != QGeoMapType() && m_plugin->name().toLatin1() == m_activeMapType.pluginName()) {
460 m_map->setActiveMapType(m_activeMapType);
462 if (!m_supportedMapTypes.isEmpty()) {
463 m_activeMapType = m_supportedMapTypes.at(0);
464 m_map->setActiveMapType(m_activeMapType);
466 m_activeMapType = QGeoMapType(QGeoMapType::NoMap,
472 QByteArrayLiteral(
""),
473 QGeoCameraCapabilities());
478 onCameraCapabilitiesChanged(m_cameraCapabilities);
484 QString copyrightString;
485 QImage copyrightImage;
486 if (!m_initialized && width() > 0 && height() > 0) {
487 QMetaObject::Connection copyrightStringCatcherConnection =
488 connect(m_map.data(), &QGeoMap::copyrightsChanged,
this,
489 [©rightString](
const QString ©){ copyrightString = copy; });
490 QMetaObject::Connection copyrightImageCatcherConnection =
491 connect(m_map.data(), &QGeoMap::copyrightsImageChanged,
this,
492 [©rightImage](
const QImage ©){ copyrightImage = copy; });
493 m_map->setViewportSize(QSize(width(), height()));
495 QObject::disconnect(copyrightStringCatcherConnection);
496 QObject::disconnect(copyrightImageCatcherConnection);
501 connect(m_map.data(), &QGeoMap::copyrightsImageChanged,
502 this, &QDeclarativeGeoMap::copyrightsImageChanged);
503 connect(m_map.data(), &QGeoMap::copyrightsChanged,
504 this, &QDeclarativeGeoMap::copyrightsChanged);
505 if (!copyrightString.isEmpty())
506 emit m_map->copyrightsChanged(copyrightString);
507 else if (!copyrightImage.isNull())
508 emit m_map->copyrightsImageChanged(copyrightImage);
512 connect(m_window, &QQuickWindow::beforeSynchronizing,
513 this, &QDeclarativeGeoMap::updateItemToWindowTransform, Qt::DirectConnection);
515 connect(m_map.data(), &QGeoMap::sgNodeChanged,
this, &QDeclarativeGeoMap::onSGNodeChanged);
516 connect(m_map.data(), &QGeoMap::cameraCapabilitiesChanged,
517 this, &QDeclarativeGeoMap::onCameraCapabilitiesChanged);
520 m_map->prefetchData();
522 connect(m_mappingManager, &QGeoMappingManager::supportedMapTypesChanged,
523 this, &QDeclarativeGeoMap::onSupportedMapTypesChanged);
524 emit minimumZoomLevelChanged(minimumZoomLevel());
525 emit maximumZoomLevelChanged(maximumZoomLevel());
526 emit supportedMapTypesChanged();
527 emit activeMapTypeChanged();
538
539
540QDeclarativeGeoServiceProvider *QDeclarativeGeoMap::plugin()
const
546
547
548
549
550
551
552void QDeclarativeGeoMap::setMinimumZoomLevel(qreal minimumZoomLevel,
bool userSet)
554 if (minimumZoomLevel >= 0) {
555 qreal oldMinimumZoomLevel =
this->minimumZoomLevel();
558 m_userMinimumZoomLevel = minimumZoomLevel;
560 m_minimumZoomLevel = minimumZoomLevel;
562 if (zoomLevel() < minimumZoomLevel)
563 setZoomLevel(minimumZoomLevel);
565 if (oldMinimumZoomLevel !=
this->minimumZoomLevel())
566 emit minimumZoomLevelChanged(
this->minimumZoomLevel());
571
572
573
574
575
576
577
578
579
580
581
582
584qreal QDeclarativeGeoMap::minimumZoomLevel()
const
586 return qMax(qMin(m_maximumZoomLevel, m_userMinimumZoomLevel), m_minimumZoomLevel);
590
591
592
593
594void QDeclarativeGeoMap::setMaximumZoomLevel(qreal maximumZoomLevel,
bool userSet)
596 if (maximumZoomLevel >= 0) {
597 qreal oldMaximumZoomLevel =
this->maximumZoomLevel();
600 m_userMaximumZoomLevel = maximumZoomLevel;
602 m_maximumZoomLevel = maximumZoomLevel;
604 if (zoomLevel() > maximumZoomLevel)
605 setZoomLevel(maximumZoomLevel);
607 if (oldMaximumZoomLevel !=
this->maximumZoomLevel())
608 emit maximumZoomLevelChanged(
this->maximumZoomLevel());
613
614
615
616
617
618
619
621qreal QDeclarativeGeoMap::maximumZoomLevel()
const
623 return qMin(qMax(m_minimumZoomLevel, m_userMaximumZoomLevel), m_maximumZoomLevel);
627
628
629
630
631
632
633
634
635
636void QDeclarativeGeoMap::setZoomLevel(qreal zoomLevel)
638 return setZoomLevel(zoomLevel, m_cameraCapabilities.overzoomEnabled());
642
643
644
645
646
647
648
649
650
651void QDeclarativeGeoMap::setZoomLevel(qreal zoomLevel,
bool overzoom)
657 QGeoCameraData cameraData = m_map->cameraData();
658 if (cameraData.zoomLevel() == zoomLevel)
661 cameraData.setZoomLevel(qBound<qreal>(overzoom ? m_map->minimumZoom() : m_cameraCapabilities.minimumZoomLevel(),
663 overzoom ? 30 : maximumZoomLevel()));
664 m_maximumViewportLatitude = m_map->maximumCenterLatitudeAtZoom(cameraData);
665 m_minimumViewportLatitude = m_map->minimumCenterLatitudeAtZoom(cameraData);
666 QGeoCoordinate coord = cameraData.center();
667 coord.setLatitude(qBound(m_minimumViewportLatitude, coord.latitude(), m_maximumViewportLatitude));
668 cameraData.setCenter(coord);
669 m_map->setCameraData(cameraData);
671 const bool zlHasChanged = zoomLevel != m_cameraData.zoomLevel();
672 m_cameraData.setZoomLevel(zoomLevel);
674 emit zoomLevelChanged(zoomLevel);
681bool QDeclarativeGeoMap::addMapChild(QObject *child)
684 QDeclarativeGeoMapItemView *mapView = qobject_cast<QDeclarativeGeoMapItemView *>(child);
686 return addMapItemView_real(mapView);
688 QDeclarativeGeoMapItemGroup *itemGroup = qobject_cast<QDeclarativeGeoMapItemGroup *>(child);
690 return addMapItemGroup_real(itemGroup);
692 QDeclarativeGeoMapItemBase *mapItem = qobject_cast<QDeclarativeGeoMapItemBase *>(child);
694 return addMapItem_real(mapItem);
699bool QDeclarativeGeoMap::removeMapChild(QObject *child)
702 QDeclarativeGeoMapItemView *mapView = qobject_cast<QDeclarativeGeoMapItemView *>(child);
704 return removeMapItemView_real(mapView);
706 QDeclarativeGeoMapItemGroup *itemGroup = qobject_cast<QDeclarativeGeoMapItemGroup *>(child);
708 return removeMapItemGroup_real(itemGroup);
710 QDeclarativeGeoMapItemBase *mapItem = qobject_cast<QDeclarativeGeoMapItemBase *>(child);
712 return removeMapItem_real(mapItem);
717bool QDeclarativeGeoMap::isGroupNested(QDeclarativeGeoMapItemGroup *group)
const
719 QObject *parent = group->parent();
723 return qobject_cast<QDeclarativeGeoMapItemGroup *>(parent)
724 || qobject_cast<QDeclarativeGeoMapItemGroup *>(group->parentItem());
727qreal QDeclarativeGeoMap::zoomLevel()
const
730 return m_map->cameraData().zoomLevel();
731 return m_cameraData.zoomLevel();
735
736
737
738
739
740
741
742
743
744void QDeclarativeGeoMap::setBearing(qreal bearing)
746 bearing = sanitizeBearing(bearing);
748 QGeoCameraData cameraData = m_map->cameraData();
749 cameraData.setBearing(bearing);
750 m_map->setCameraData(cameraData);
752 const bool bearingHasChanged = bearing != m_cameraData.bearing();
753 m_cameraData.setBearing(bearing);
754 if (bearingHasChanged) {
755 emit bearingChanged(bearing);
763
764
765
766
767
768
769
770
771
772
773
774void QDeclarativeGeoMap::setBearing(qreal bearing,
const QGeoCoordinate &coordinate)
779 const QGeoCoordinate currentCenter = center();
780 const qreal currentBearing = QDeclarativeGeoMap::bearing();
781 bearing = sanitizeBearing(bearing);
783 if (!coordinate.isValid()
784 || !qIsFinite(bearing)
785 || (coordinate == currentCenter && bearing == currentBearing))
788 if (m_map->capabilities() & QGeoMap::SupportsSetBearing)
789 m_map->setBearing(bearing, coordinate);
792qreal QDeclarativeGeoMap::bearing()
const
795 return m_map->cameraData().bearing();
796 return m_cameraData.bearing();
800
801
802
803
804
805
806
807
808
809
810
811void QDeclarativeGeoMap::setTilt(qreal tilt)
813 tilt = qBound(minimumTilt(), tilt, maximumTilt());
816 QGeoCameraData cameraData = m_map->cameraData();
817 cameraData.setTilt(tilt);
818 m_map->setCameraData(cameraData);
820 const bool tiltHasChanged = tilt != m_cameraData.tilt();
821 m_cameraData.setTilt(tilt);
822 if (tiltHasChanged) {
823 emit tiltChanged(tilt);
830qreal QDeclarativeGeoMap::tilt()
const
833 return m_map->cameraData().tilt();
834 return m_cameraData.tilt();
837void QDeclarativeGeoMap::setMinimumTilt(qreal minimumTilt,
bool userSet)
839 if (minimumTilt >= 0) {
840 qreal oldMinimumTilt =
this->minimumTilt();
843 m_userMinimumTilt = minimumTilt;
845 m_minimumTilt = minimumTilt;
847 if (tilt() < minimumTilt)
848 setTilt(minimumTilt);
850 if (oldMinimumTilt !=
this->minimumTilt())
851 emit minimumTiltChanged(
this->minimumTilt());
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871void QDeclarativeGeoMap::setFieldOfView(qreal fieldOfView)
873 fieldOfView = qBound(minimumFieldOfView(), fieldOfView, maximumFieldOfView());
876 QGeoCameraData cameraData = m_map->cameraData();
877 cameraData.setFieldOfView(fieldOfView);
878 m_map->setCameraData(cameraData);
880 const bool fovChanged = fieldOfView != m_cameraData.fieldOfView();
881 m_cameraData.setFieldOfView(fieldOfView);
883 emit fieldOfViewChanged(fieldOfView);
890qreal QDeclarativeGeoMap::fieldOfView()
const
893 return m_map->cameraData().fieldOfView();
894 return m_cameraData.fieldOfView();
897void QDeclarativeGeoMap::setMinimumFieldOfView(qreal minimumFieldOfView,
bool userSet)
899 if (minimumFieldOfView > 0 && minimumFieldOfView < 180.0) {
900 qreal oldMinimumFoV =
this->minimumFieldOfView();
903 m_userMinimumFieldOfView = minimumFieldOfView;
905 m_minimumFieldOfView = minimumFieldOfView;
907 if (fieldOfView() < minimumFieldOfView)
908 setFieldOfView(minimumFieldOfView);
910 if (oldMinimumFoV !=
this->minimumFieldOfView())
911 emit minimumFieldOfViewChanged(
this->minimumFieldOfView());
916
917
918
919
920
921
922
923
924
925
926
927
928qreal QDeclarativeGeoMap::minimumFieldOfView()
const
930 return qMax(qMin(m_maximumFieldOfView, m_userMinimumFieldOfView), m_minimumFieldOfView);
933void QDeclarativeGeoMap::setMaximumFieldOfView(qreal maximumFieldOfView,
bool userSet)
935 if (maximumFieldOfView > 0 && maximumFieldOfView < 180.0) {
936 qreal oldMaximumFoV =
this->maximumFieldOfView();
938 m_userMaximumFieldOfView = maximumFieldOfView;
940 m_maximumFieldOfView = maximumFieldOfView;
942 if (fieldOfView() > maximumFieldOfView)
943 setFieldOfView(maximumFieldOfView);
945 if (oldMaximumFoV !=
this->maximumFieldOfView())
946 emit maximumFieldOfViewChanged(
this->maximumFieldOfView());
951
952
953
954
955
956
957
958
959
960
961
962
963qreal QDeclarativeGeoMap::maximumFieldOfView()
const
965 return qMin(qMax(m_minimumFieldOfView, m_userMaximumFieldOfView), m_maximumFieldOfView);
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983qreal QDeclarativeGeoMap::minimumTilt()
const
985 return qMax(qMin(m_maximumTilt, m_userMinimumTilt), m_minimumTilt);
988void QDeclarativeGeoMap::setMaximumTilt(qreal maximumTilt,
bool userSet)
990 if (maximumTilt >= 0) {
991 qreal oldMaximumTilt =
this->maximumTilt();
994 m_userMaximumTilt = maximumTilt;
996 m_maximumTilt = maximumTilt;
998 if (tilt() > maximumTilt)
999 setTilt(maximumTilt);
1001 if (oldMaximumTilt !=
this->maximumTilt())
1002 emit maximumTiltChanged(
this->maximumTilt());
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021qreal QDeclarativeGeoMap::maximumTilt()
const
1023 return qMin(qMax(m_minimumTilt, m_userMaximumTilt), m_maximumTilt);
1027
1028
1029
1030
1031
1032
1033
1034void QDeclarativeGeoMap::setCenter(
const QGeoCoordinate ¢er)
1036 if (!center.isValid())
1039 if (m_initialized) {
1040 QGeoCoordinate coord(center);
1041 coord.setLatitude(qBound(m_minimumViewportLatitude, center.latitude(), m_maximumViewportLatitude));
1042 QGeoCameraData cameraData = m_map->cameraData();
1043 cameraData.setCenter(coord);
1044 m_map->setCameraData(cameraData);
1046 const bool centerHasChanged = center != m_cameraData.center();
1047 m_cameraData.setCenter(center);
1048 if (centerHasChanged) {
1049 emit centerChanged(center);
1056QGeoCoordinate QDeclarativeGeoMap::center()
const
1059 return m_map->cameraData().center();
1060 return m_cameraData.center();
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082void QDeclarativeGeoMap::setVisibleRegion(
const QGeoShape &shape)
1084 if (shape.boundingGeoRectangle() == visibleRegion())
1087 m_visibleRegion = shape.boundingGeoRectangle();
1088 if (!m_visibleRegion.isValid()
1089 || (m_visibleRegion.bottomRight().latitude() >= 85.0)
1090 || (m_visibleRegion.topLeft().latitude() <= -85.0)) {
1092 m_visibleRegion = QGeoRectangle();
1093 m_pendingFitViewport =
false;
1094 emit visibleRegionChanged();
1098 if (!m_map || !width() || !height()) {
1099 m_pendingFitViewport =
true;
1100 emit visibleRegionChanged();
1104 fitViewportToGeoShape(m_visibleRegion);
1105 emit visibleRegionChanged();
1108QGeoShape QDeclarativeGeoMap::visibleRegion()
const
1110 if (!m_map || !width() || !height())
1111 return m_visibleRegion;
1113 if (m_map->capabilities() & QGeoMap::SupportsVisibleRegion) {
1114 return m_map->visibleRegion();
1118 QList<QGeoCoordinate> visiblePoly;
1119 visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(0,0),
false);
1120 visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_map->viewportWidth() - 1,
1122 visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_map->viewportWidth() - 1,
1123 m_map->viewportHeight() - 1),
false);
1124 visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(0,
1125 m_map->viewportHeight() - 1),
false);
1127 path.setPath(visiblePoly);
1128 return path.boundingGeoRectangle();
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143void QDeclarativeGeoMap::setCopyrightsVisible(
bool visible)
1145 if (m_copyrightsVisible == visible)
1148 if (!m_copyrights.isNull())
1149 m_copyrights->setCopyrightsVisible(visible);
1151 m_copyrightsVisible = visible;
1152 emit copyrightsVisibleChanged(visible);
1155bool QDeclarativeGeoMap::copyrightsVisible()
const
1157 return m_copyrightsVisible;
1163
1164
1165
1166
1167
1168
1169void QDeclarativeGeoMap::setColor(
const QColor &color)
1171 if (color != m_color) {
1174 emit colorChanged(m_color);
1178QColor QDeclarativeGeoMap::color()
const
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193QRectF QDeclarativeGeoMap::visibleArea()
const
1196 return m_map->visibleArea();
1197 return m_visibleArea;
1200void QDeclarativeGeoMap::setVisibleArea(
const QRectF &visibleArea)
1202 const QRectF oldVisibleArea = QDeclarativeGeoMap::visibleArea();
1203 if (visibleArea == oldVisibleArea)
1206 if (!visibleArea.isValid() && !visibleArea.isEmpty())
1209 if (m_initialized) {
1210 m_map->setVisibleArea(visibleArea);
1211 const QRectF newVisibleArea = QDeclarativeGeoMap::visibleArea();
1212 if (newVisibleArea != oldVisibleArea) {
1214 for (
const QPointer<QDeclarativeGeoMapItemBase> &i: std::as_const(m_mapItems)) {
1216 i->visibleAreaChanged();
1220 m_visibleArea = visibleArea;
1221 const QRectF newVisibleArea = QDeclarativeGeoMap::visibleArea();
1222 if (newVisibleArea != oldVisibleArea)
1223 emit visibleAreaChanged();
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237bool QDeclarativeGeoMap::mapReady()
const
1239 return m_initialized;
1242QMargins QDeclarativeGeoMap::mapMargins()
const
1244 const QRectF va = m_map->visibleArea();
1247 return QMargins( va.x()
1249 , width() - va.width() - va.x()
1250 , height() - va.height() - va.y());
1254
1255
1256
1257
1258
1259
1260QList<QGeoMapType> QDeclarativeGeoMap::supportedMapTypes()
1262 return m_supportedMapTypes;
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283void QDeclarativeGeoMap::alignCoordinateToPoint(
const QGeoCoordinate &coordinate,
const QPointF &point)
1285 if (!m_map || !(m_map->capabilities() & QGeoMap::SupportsAnchoringCoordinate))
1288 if (!coordinate.isValid()
1289 || !qIsFinite(point.x())
1290 || !qIsFinite(point.y()))
1293 m_map->anchorCoordinateToPoint(coordinate, point);
1297
1298
1299
1300
1301
1302
1303
1304QGeoCoordinate QDeclarativeGeoMap::toCoordinate(
const QPointF &position,
bool clipToViewPort)
const
1307 return m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(position), clipToViewPort);
1309 return QGeoCoordinate();
1313
1314
1315
1316
1317
1318
1319
1320QPointF QDeclarativeGeoMap::fromCoordinate(
const QGeoCoordinate &coordinate,
bool clipToViewPort)
const
1323 return m_map->geoProjection().coordinateToItemPosition(coordinate, clipToViewPort).toPointF();
1325 return QPointF(qQNaN(), qQNaN());
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339void QDeclarativeGeoMap::pan(
int dx,
int dy)
1343 if (dx == 0 && dy == 0)
1346 QGeoCoordinate coord = m_map->geoProjection().itemPositionToCoordinate(
1347 QDoubleVector2D(m_map->viewportWidth() / 2 + dx,
1348 m_map->viewportHeight() / 2 + dy));
1354
1355
1356
1357
1358void QDeclarativeGeoMap::prefetchData()
1362 m_map->prefetchData();
1366
1367
1368
1369
1370
1371
1372void QDeclarativeGeoMap::clearData()
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390void QDeclarativeGeoMap::fitViewportToGeoShape(
const QGeoShape &shape, QVariant margins)
1392 QMargins m(10, 10, 10, 10);
1393 switch (margins.typeId()) {
1394 case QMetaType::Int:
1395 case QMetaType::Double: {
1396 const int value =
int(margins.toDouble());
1397 m = QMargins(value, value, value, value);
1404 fitViewportToGeoShape(shape, m);
1407void QDeclarativeGeoMap::fitViewportToGeoShape(
const QGeoShape &shape,
const QMargins &borders)
1409 if (!m_map || !shape.isValid())
1412 if (m_map->geoProjection().projectionType() == QGeoProjection::ProjectionWebMercator) {
1415 const QMargins margins = borders + mapMargins();
1416 const QGeoProjectionWebMercator &p =
static_cast<
const QGeoProjectionWebMercator&>(m_map->geoProjection());
1417 const QPair<QGeoCoordinate, qreal> fitData = p.fitViewportToGeoRectangle(shape.boundingGeoRectangle(),
1419 if (!fitData.first.isValid())
1423 setProperty(
"center", QVariant::fromValue(fitData.first));
1425 if (!qIsFinite(fitData.second))
1427 double newZoom = qMax<
double>(minimumZoomLevel(), fitData.second);
1428 setProperty(
"zoomLevel", QVariant::fromValue(newZoom));
1429 }
else if (m_map->capabilities() & QGeoMap::SupportsFittingViewportToGeoRectangle) {
1431 m_map->fitViewportToGeoRectangle(m_visibleRegion, borders);
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1448QString QDeclarativeGeoMap::errorString()
const
1450 return m_errorString;
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1469QGeoServiceProvider::Error QDeclarativeGeoMap::error()
const
1474QGeoMap *QDeclarativeGeoMap::map()
const
1479void QDeclarativeGeoMap::itemChange(ItemChange change,
const ItemChangeData &value)
1481 if (change == ItemChildAddedChange) {
1482 QQuickItem *child = value.item;
1483 QQuickItem *mapItem = qobject_cast<QDeclarativeGeoMapItemBase *>(child);
1485 mapItem = qobject_cast<QDeclarativeGeoMapItemGroup *>(child);
1488 qreal z = mapItem->z();
1489 if (z > m_maxChildZ) {
1493 m_copyrights->setCopyrightsZ(m_maxChildZ + 1);
1496 }
else if (change == ItemSceneChange) {
1498 disconnect(m_window, &QQuickWindow::beforeSynchronizing,
1499 this, &QDeclarativeGeoMap::updateItemToWindowTransform);
1501 m_window = value.window;
1503 connect(m_window, &QQuickWindow::beforeSynchronizing,
1504 this, &QDeclarativeGeoMap::updateItemToWindowTransform, Qt::DirectConnection);
1507 QQuickItem::itemChange(change, value);
1510void QDeclarativeGeoMap::attachCopyrightNotice(
bool initialVisibility)
1512 if (initialVisibility) {
1513 ++m_copyNoticesVisible;
1515 m_map->setCopyrightVisible(m_copyNoticesVisible > 0);
1519void QDeclarativeGeoMap::detachCopyrightNotice(
bool currentVisibility)
1521 if (currentVisibility) {
1522 --m_copyNoticesVisible;
1524 m_map->setCopyrightVisible(m_copyNoticesVisible > 0);
1528void QDeclarativeGeoMap::onAttachedCopyrightNoticeVisibilityChanged()
1530 QDeclarativeGeoMapCopyrightNotice *copy =
static_cast<QDeclarativeGeoMapCopyrightNotice *>(sender());
1531 m_copyNoticesVisible += (
int(copy->copyrightsVisible()) * 2 - 1);
1533 m_map->setCopyrightVisible(m_copyNoticesVisible > 0);
1536void QDeclarativeGeoMap::onCameraDataChanged(
const QGeoCameraData &cameraData)
1538 bool centerHasChanged = cameraData.center() != m_cameraData.center();
1539 bool bearingHasChanged = cameraData.bearing() != m_cameraData.bearing();
1540 bool tiltHasChanged = cameraData.tilt() != m_cameraData.tilt();
1541 bool fovHasChanged = cameraData.fieldOfView() != m_cameraData.fieldOfView();
1542 bool zoomHasChanged = cameraData.zoomLevel() != m_cameraData.zoomLevel();
1544 m_cameraData = cameraData;
1546 for (
const QPointer<QDeclarativeGeoMapItemBase> &i: std::as_const(m_mapItems)) {
1548 i->baseCameraDataChanged(m_cameraData);
1551 if (centerHasChanged)
1552 emit centerChanged(m_cameraData.center());
1554 emit zoomLevelChanged(m_cameraData.zoomLevel());
1555 if (bearingHasChanged)
1556 emit bearingChanged(m_cameraData.bearing());
1558 emit tiltChanged(m_cameraData.tilt());
1560 emit fieldOfViewChanged(m_cameraData.fieldOfView());
1561 if (centerHasChanged || zoomHasChanged || bearingHasChanged
1562 || tiltHasChanged || fovHasChanged)
1563 emit visibleRegionChanged();
1567
1568
1569
1570
1571
1572
1573
1574
1575
1577QList<QObject *> QDeclarativeGeoMap::mapItems()
1579 QList<QObject *> ret;
1580 for (
const auto &ptr : m_mapItems) {
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1605void QDeclarativeGeoMap::addMapItem(QDeclarativeGeoMapItemBase *item)
1607 if (addMapItem_real(item))
1608 emit mapItemsChanged();
1611bool QDeclarativeGeoMap::addMapItem_real(QDeclarativeGeoMapItemBase *item)
1613 if (!item || item->quickMap())
1616 if (!qobject_cast<QDeclarativeGeoMapItemGroup *>(item->parentItem()))
1617 item->setParentItem(
this);
1618 m_mapItems.append(item);
1620 item->setMap(
this, m_map);
1621 m_map->addMapItem(item);
1627
1628
1629
1630
1631
1632
1633
1634
1635void QDeclarativeGeoMap::removeMapItem(QDeclarativeGeoMapItemBase *ptr)
1637 if (removeMapItem_real(ptr))
1638 emit mapItemsChanged();
1641bool QDeclarativeGeoMap::removeMapItem_real(QDeclarativeGeoMapItemBase *ptr)
1645 QPointer<QDeclarativeGeoMapItemBase> item(ptr);
1646 if (!m_mapItems.contains(item))
1649 m_map->removeMapItem(ptr);
1650 if (item->parentItem() ==
this)
1651 item->setParentItem(0);
1654 m_mapItems.removeOne(item);
1659
1660
1661
1662
1663
1664
1665void QDeclarativeGeoMap::clearMapItems()
1667 if (m_mapItems.isEmpty())
1670 qsizetype removed = 0;
1671 for (qsizetype i = 0; i < m_mapItemGroups.count(); ++i) {
1672 auto item = m_mapItemGroups.at(i);
1674 if (qobject_cast<QDeclarativeGeoMapItemView *>(item))
1678 if (item->parentItem() !=
this)
1681 if (removeMapItemGroup_real(item)) {
1687 while (!m_mapItems.isEmpty())
1688 removed += removeMapItem_real(m_mapItems.first());
1691 emit mapItemsChanged();
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704void QDeclarativeGeoMap::addMapItemGroup(QDeclarativeGeoMapItemGroup *itemGroup)
1706 if (addMapItemGroup_real(itemGroup))
1707 emit mapItemsChanged();
1710bool QDeclarativeGeoMap::addMapItemGroup_real(QDeclarativeGeoMapItemGroup *itemGroup)
1712 if (!itemGroup || itemGroup->quickMap())
1715 itemGroup->setQuickMap(
this);
1717 if (!isGroupNested(itemGroup))
1718 itemGroup->setParentItem(
this);
1720 QPointer<QDeclarativeGeoMapItemGroup> g(itemGroup);
1721 m_mapItemGroups.append(g);
1723 const QList<QQuickItem *> quickKids = itemGroup->childItems();
1725 for (
auto c: quickKids) {
1726 count += addMapChild(c);
1732
1733
1734
1735
1736
1737
1738
1739
1740void QDeclarativeGeoMap::removeMapItemGroup(QDeclarativeGeoMapItemGroup *itemGroup)
1742 if (removeMapItemGroup_real(itemGroup))
1743 emit mapItemsChanged();
1746bool QDeclarativeGeoMap::removeMapItemGroup_real(QDeclarativeGeoMapItemGroup *itemGroup)
1748 if (!itemGroup || itemGroup->quickMap() !=
this)
1751 QPointer<QDeclarativeGeoMapItemGroup> g(itemGroup);
1752 if (!m_mapItemGroups.removeOne(g))
1755 const QList<QQuickItem *> quickKids = itemGroup->childItems();
1757 for (
auto c: quickKids) {
1758 count += removeMapChild(c);
1760 itemGroup->setQuickMap(
nullptr);
1761 if (itemGroup->parentItem() ==
this)
1762 itemGroup->setParentItem(0);
1767
1768
1769
1770
1771
1772
1773
1774
1775void QDeclarativeGeoMap::removeMapItemView(QDeclarativeGeoMapItemView *itemView)
1777 if (removeMapItemView_real(itemView))
1778 emit mapItemsChanged();
1781bool QDeclarativeGeoMap::removeMapItemView_real(QDeclarativeGeoMapItemView *itemView)
1783 if (!itemView || itemView->m_map !=
this)
1786 itemView->removeInstantiatedItems(
false);
1787 itemView->m_map = 0;
1788 m_mapViews.removeOne(itemView);
1789 return removeMapItemGroup_real(itemView);
1792void QDeclarativeGeoMap::updateItemToWindowTransform()
1798 QTransform item2Window = QQuickItemPrivate::get(
this)->itemToWindowTransform();
1799 if (!property(
"layer").isNull() && property(
"layer").value<QObject *>()->property(
"enabled").toBool())
1800 item2Window.reset();
1802 m_map->setItemToWindowTransform(item2Window);
1804 m_sgNodeHasChanged =
false;
1807void QDeclarativeGeoMap::onSGNodeChanged()
1809 m_sgNodeHasChanged =
true;
1814
1815
1816
1817
1818
1819
1820
1821
1822void QDeclarativeGeoMap::addMapItemView(QDeclarativeGeoMapItemView *itemView)
1824 if (addMapItemView_real(itemView))
1825 emit mapItemsChanged();
1828bool QDeclarativeGeoMap::addMapItemView_real(QDeclarativeGeoMapItemView *itemView)
1830 if (!itemView || itemView->m_map)
1833 int count = addMapItemGroup_real(itemView);
1836 m_mapViews.append(itemView);
1837 setupMapView(itemView);
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851void QDeclarativeGeoMap::setActiveMapType(
const QGeoMapType &mapType)
1853 if (m_activeMapType != mapType) {
1855 if (mapType.pluginName() == m_plugin->name().toLatin1()) {
1856 m_map->setActiveMapType(mapType);
1857 m_activeMapType = mapType;
1858 emit activeMapTypeChanged();
1861 m_activeMapType = mapType;
1862 emit activeMapTypeChanged();
1867QGeoMapType QDeclarativeGeoMap::activeMapType()
const
1869 return m_activeMapType;
1873
1874
1875void QDeclarativeGeoMap::geometryChange(
const QRectF &newGeometry,
const QRectF &oldGeometry)
1877 QQuickItem::geometryChange(newGeometry, oldGeometry);
1879 if (!m_map || newGeometry.size().isEmpty())
1882 m_map->setViewportSize(newGeometry.size().toSize());
1884 if (!m_initialized) {
1887 setMinimumZoomLevel(m_map->minimumZoom(),
false);
1890 QGeoCameraData cameraData = m_map->cameraData();
1891 const double maximumCenterLatitudeAtZoom = m_map->maximumCenterLatitudeAtZoom(cameraData);
1892 const double minimumCenterLatitudeAtZoom = m_map->minimumCenterLatitudeAtZoom(cameraData);
1893 if (maximumCenterLatitudeAtZoom != m_maximumViewportLatitude
1894 || minimumCenterLatitudeAtZoom != m_minimumViewportLatitude) {
1895 m_maximumViewportLatitude = maximumCenterLatitudeAtZoom;
1896 m_minimumViewportLatitude = minimumCenterLatitudeAtZoom;
1897 QGeoCoordinate coord = cameraData.center();
1898 coord.setLatitude(qBound(m_minimumViewportLatitude, coord.latitude(), m_maximumViewportLatitude));
1899 cameraData.setCenter(coord);
1900 m_map->setCameraData(cameraData);
1902 if (oldGeometry.size() != newGeometry.size()) {
1904 for (
const QPointer<QDeclarativeGeoMapItemBase> &i: std::as_const(m_mapItems)) {
1906 i->polishAndUpdate();
1912
1913
1914
1915
1916
1917
1918
1919 if (m_pendingFitViewport && width() && height()) {
1920 fitViewportToGeoShape(m_visibleRegion);
1921 m_pendingFitViewport =
false;
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939void QDeclarativeGeoMap::fitViewportToMapItems(
const QVariantList &items)
1942 QList<QPointer<QDeclarativeGeoMapItemBase> > itms;
1943 for (
const QVariant &i: items) {
1944 QDeclarativeGeoMapItemBase *itm = qobject_cast<QDeclarativeGeoMapItemBase *>(i.value<QObject *>());
1948 fitViewportToMapItemsRefine(itms,
true,
false);
1950 fitViewportToMapItemsRefine(m_mapItems,
true,
false);
1955
1956
1957
1958
1959
1960
1961
1962
1963void QDeclarativeGeoMap::fitViewportToVisibleMapItems()
1965 fitViewportToMapItemsRefine(m_mapItems,
true,
true);
1969
1970
1971void QDeclarativeGeoMap::fitViewportToMapItemsRefine(
const QList<QPointer<QDeclarativeGeoMapItemBase> > &mapItems,
1978 if (mapItems.size() == 0)
1981 double minX = qInf();
1982 double maxX = -qInf();
1983 double minY = qInf();
1984 double maxY = -qInf();
1985 double topLeftX = 0;
1986 double topLeftY = 0;
1987 double bottomRightX = 0;
1988 double bottomRightY = 0;
1989 bool haveQuickItem =
false;
1992 qsizetype itemCount = 0;
1993 for (qsizetype i = 0; i < mapItems.count(); ++i) {
1994 if (!mapItems.at(i))
1996 QDeclarativeGeoMapItemBase *item = mapItems.at(i).data();
1997 if (!item || (onlyVisible && (!item->isVisible() || item->mapItemOpacity() <= 0.0)))
2001 QDeclarativeGeoMapQuickItem *quickItem =
2002 qobject_cast<QDeclarativeGeoMapQuickItem*>(item);
2003 if (refine && quickItem) {
2004 haveQuickItem =
true;
2015 if (item->isPolishScheduled())
2016 item->updatePolish();
2018 if (quickItem && quickItem->matrix_ && !quickItem->matrix_->m_matrix.isIdentity()) {
2020 if (quickItem->zoomLevel() == 0.0)
2023 QRectF brect = item->boundingRect();
2024 brect = quickItem->matrix_->m_matrix.mapRect(brect);
2025 QPointF transformedPosition = quickItem->matrix_->m_matrix.map(item->position());
2026 topLeftX = transformedPosition.x();
2027 topLeftY = transformedPosition.y();
2028 bottomRightX = topLeftX + brect.width();
2029 bottomRightY = topLeftY + brect.height();
2031 QGeoRectangle brect = item->geoShape().boundingGeoRectangle();
2032 topLeftX = fromCoordinate(brect.topLeft(),
false).x();
2033 topLeftY = fromCoordinate(brect.topLeft(),
false).y();
2034 bottomRightX = fromCoordinate(brect.bottomRight(),
false).x();
2035 bottomRightY = fromCoordinate(brect.bottomRight(),
false).y();
2038 minX = qMin(minX, topLeftX);
2039 maxX = qMax(maxX, bottomRightX);
2040 minY = qMin(minY, topLeftY);
2041 maxY = qMax(maxY, bottomRightY);
2046 if (itemCount == 0) {
2048 fitViewportToMapItemsRefine(mapItems,
false, onlyVisible);
2051 double bboxWidth = maxX - minX;
2052 double bboxHeight = maxY - minY;
2053 double bboxCenterX = minX + (bboxWidth / 2.0);
2054 double bboxCenterY = minY + (bboxHeight / 2.0);
2057 QGeoCoordinate coordinate;
2058 coordinate = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(bboxCenterX, bboxCenterY),
false);
2059 setProperty(
"center", QVariant::fromValue(coordinate));
2062 double bboxWidthRatio = bboxWidth / (bboxWidth + bboxHeight);
2063 double mapWidthRatio = width() / (width() + height());
2066 if (bboxWidthRatio > mapWidthRatio)
2067 zoomRatio = bboxWidth / width();
2069 zoomRatio = bboxHeight / height();
2071 qreal newZoom = std::log10(zoomRatio) / std::log10(0.5);
2072 newZoom = std::floor(qMax(minimumZoomLevel(), (zoomLevel() + newZoom)));
2073 setProperty(
"zoomLevel", QVariant::fromValue(newZoom));
2078 fitViewportToMapItemsRefine(mapItems,
false, onlyVisible);