1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the QtLocation module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "qdeclarativegeomapitemgroup_p.h"
38#include "qdeclarativegeomapitembase_p.h"
39#include "qdeclarativegeomap_p.h"
40
41QT_BEGIN_NAMESPACE
42
43/*!
44 \qmltype MapItemGroup
45 \instantiates QDeclarativeGeoMapItemGroup
46 \inqmlmodule QtLocation
47 \ingroup qml-QtLocation5-maps
48 \since QtLocation 5.9
49
50 \brief The MapItemGroup type is a container for map items.
51
52 Its purpose is to enable code modularization by allowing the usage
53 of qml files containing map elements related to each other, and
54 the associated bindings.
55
56 \note The release of this API with Qt 5.9 is a Technology Preview.
57
58 \section2 Example Usage
59
60 The following snippet shows how to use a MapItemGroup to create a MapCircle, centered at
61 the coordinate (63, -18) with a radius of 100km, filled in red, surrounded by an ondulated green border,
62 both contained in a semitransparent blue circle with a MouseArea that moves the whole group.
63 This group is defined in a separate file named PolygonGroup.qml:
64
65 \code
66 import QtQuick 2.4
67 import QtPositioning 5.6
68 import QtLocation 5.9
69
70 MapItemGroup {
71 id: itemGroup
72 property alias position: mainCircle.center
73 property var radius: 100 * 1000
74 property var borderHeightPct : 0.3
75
76 MapCircle {
77 id: mainCircle
78 center : QtPositioning.coordinate(40, 0)
79 radius: itemGroup.radius * (1.0 + borderHeightPct)
80 opacity: 0.05
81 visible: true
82 color: 'blue'
83
84 MouseArea{
85 anchors.fill: parent
86 drag.target: parent
87 id: maItemGroup
88 }
89 }
90
91 MapCircle {
92 id: groupCircle
93 center: itemGroup.position
94 radius: itemGroup.radius
95 color: 'crimson'
96
97 onCenterChanged: {
98 groupPolyline.populateBorder();
99 }
100 }
101
102 MapPolyline {
103 id: groupPolyline
104 line.color: 'green'
105 line.width: 3
106
107 function populateBorder() {
108 groupPolyline.path = [] // clearing the path
109 var waveLength = 8.0;
110 var waveAmplitude = groupCircle.radius * borderHeightPct;
111 for (var i=0; i <= 360; i++) {
112 var wavePhase = (i/360.0 * 2.0 * Math.PI )* waveLength
113 var waveHeight = (Math.cos(wavePhase) + 1.0) / 2.0
114 groupPolyline.addCoordinate(groupCircle.center.atDistanceAndAzimuth(groupCircle.radius + waveAmplitude * waveHeight , i))
115 }
116 }
117
118 Component.onCompleted: {
119 populateBorder()
120 }
121 }
122 }
123 \endcode
124
125 PolygonGroup.qml is now a reusable component that can then be used in a Map as:
126
127 \code
128 Map {
129 id: map
130 PolygonGroup {
131 id: polygonGroup
132 position: QtPositioning.coordinate(63,-18)
133 }
134 }
135 \endcode
136
137 \image api-mapitemgroup.png
138*/
139
140QDeclarativeGeoMapItemGroup::QDeclarativeGeoMapItemGroup(QQuickItem *parent)
141: QQuickItem(parent), m_quickMap(nullptr)
142{
143 connect(sender: this, signal: &QQuickItem::opacityChanged,
144 receiver: this, slot: &QDeclarativeGeoMapItemGroup::mapItemOpacityChanged);
145}
146
147QDeclarativeGeoMapItemGroup::~QDeclarativeGeoMapItemGroup()
148{
149
150}
151
152void QDeclarativeGeoMapItemGroup::setParentGroup(QDeclarativeGeoMapItemGroup &parentGroup)
153{
154 m_parentGroup = &parentGroup;
155 connect(sender: m_parentGroup, signal: &QDeclarativeGeoMapItemGroup::mapItemOpacityChanged,
156 receiver: this, slot: &QDeclarativeGeoMapItemGroup::mapItemOpacityChanged);
157}
158
159void QDeclarativeGeoMapItemGroup::setQuickMap(QDeclarativeGeoMap *quickMap)
160{
161 if (!quickMap && m_quickMap)
162 m_quickMap->disconnect(receiver: this);
163 m_quickMap = quickMap;
164 if (m_quickMap) {
165 onMapSizeChanged();
166 connect(sender: m_quickMap, signal: &QQuickItem::widthChanged, receiver: this, slot: &QDeclarativeGeoMapItemGroup::onMapSizeChanged);
167 connect(sender: m_quickMap, signal: &QQuickItem::heightChanged, receiver: this, slot: &QDeclarativeGeoMapItemGroup::onMapSizeChanged);
168 }
169}
170
171QDeclarativeGeoMap *QDeclarativeGeoMapItemGroup::quickMap() const
172{
173 return m_quickMap;
174}
175
176qreal QDeclarativeGeoMapItemGroup::mapItemOpacity() const
177{
178 return ((m_parentGroup) ? m_parentGroup->mapItemOpacity() : 1.0) * opacity();
179}
180
181void QDeclarativeGeoMapItemGroup::classBegin()
182{
183 QQuickItem::classBegin();
184}
185
186void QDeclarativeGeoMapItemGroup::componentComplete()
187{
188 QQuickItem::componentComplete();
189
190 // In certain cases the parent won't be set via the constructor, but rather later on
191 // during the instantiation/incubation process.
192 // Therefore calling setParentGroup here, when the parent is known.
193 // The childrenChanged use case to handle dynamically-added items is currently unsupported.
194 const QList<QQuickItem *> &quickKids = childItems();
195 for (QQuickItem *k : quickKids) {
196 QDeclarativeGeoMapItemGroup *childGroup
197 = qobject_cast<QDeclarativeGeoMapItemGroup *>(object: k);
198 if (childGroup) {
199 childGroup->setParentGroup(*this);
200 continue;
201 }
202 QDeclarativeGeoMapItemBase *childItem
203 = qobject_cast<QDeclarativeGeoMapItemBase *>(object: k);
204 if (childItem) {
205 childItem->setParentGroup(*this);
206 continue;
207 }
208 }
209}
210
211void QDeclarativeGeoMapItemGroup::onMapSizeChanged()
212{
213 setWidth(m_quickMap->width());
214 setHeight(m_quickMap->height());
215}
216
217QT_END_NAMESPACE
218

source code of qtlocation/src/location/declarativemaps/qdeclarativegeomapitemgroup.cpp