1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 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 "qmappolylineobjectqsg_p_p.h"
38 #include <QtQuick/qsgnode.h>
39 #include <QtQuick/qsgsimplerectnode.h>
40
41 QT_BEGIN_NAMESPACE
42
43 /*
44 Note: never use q, since this class is also used inside QMapRouteObjectPrivateQSG!
45 */
46
QMapPolylineObjectPrivateQSG(QGeoMapObject * q)47 QMapPolylineObjectPrivateQSG::QMapPolylineObjectPrivateQSG(QGeoMapObject *q)
48 : QMapPolylineObjectPrivateDefault(q)
49 {
50
51 }
52
QMapPolylineObjectPrivateQSG(const QMapPolylineObjectPrivate & other)53 QMapPolylineObjectPrivateQSG::QMapPolylineObjectPrivateQSG(const QMapPolylineObjectPrivate &other)
54 : QMapPolylineObjectPrivateDefault(other)
55 {
56 // rest of the data already cloned by the *Default copy constructor, but necessary
57 // update operations triggered only by setters overrides
58 markSourceDirty();
59 updateGeometry();
60 if (m_map)
61 emit m_map->sgNodeChanged();
62 }
63
~QMapPolylineObjectPrivateQSG()64 QMapPolylineObjectPrivateQSG::~QMapPolylineObjectPrivateQSG()
65 {
66 if (m_map)
67 m_map->removeMapObject(q);
68 }
69
projectPath()70 QList<QDoubleVector2D> QMapPolylineObjectPrivateQSG::projectPath()
71 {
72 QList<QDoubleVector2D> geopathProjected_;
73 if (!m_map || m_map->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
74 return geopathProjected_;
75
76 const QGeoProjectionWebMercator &p =
77 static_cast<const QGeoProjectionWebMercator&>(m_map->geoProjection());
78 geopathProjected_.reserve(m_path.path().size());
79 for (const QGeoCoordinate &c : m_path.path())
80 geopathProjected_ << p.geoToMapProjection(c);
81 return geopathProjected_;
82 }
83
updateGeometry()84 void QMapPolylineObjectPrivateQSG::updateGeometry()
85 {
86 if (!m_map || m_map->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
87 return;
88
89 if (m_path.path().length() == 0) { // Possibly cleared
90 m_borderGeometry.clear();
91 return;
92 }
93
94 const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(m_map->geoProjection());
95 if (m_borderGeometry.isSourceDirty()) {
96 m_borderGeometry.setPreserveGeometry(true, m_path.boundingGeoRectangle().topLeft());
97 m_borderGeometry.m_dataChanged = true;
98 m_borderGeometry.updateSourcePoints(*m_map, m_path);
99 m_leftBoundMercator = p.geoToMapProjection(m_borderGeometry.origin());
100 }
101 m_borderGeometry.markScreenDirty();
102 m_borderGeometry.m_wrapOffset = p.projectionWrapFactor(m_leftBoundMercator) + 1;
103 }
104
105 /*!
106 \internal
107 */
zoomForLOD(int zoom) const108 unsigned int QMapPolylineObjectPrivateQSG::zoomForLOD(int zoom) const
109 {
110 // LOD Threshold currently fixed to 12 for MapPolylineObject(QSG).
111 // ToDo: Consider allowing to change this via DynamicParameter.
112 if (zoom >= 12)
113 return 30;
114 return uint(zoom);
115 }
116
updateMapObjectNode(QSGNode * oldNode,VisibleNode ** visibleNode,QSGNode * root,QQuickWindow *)117 QSGNode *QMapPolylineObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
118 VisibleNode **visibleNode,
119 QSGNode *root,
120 QQuickWindow * /*window*/)
121 {
122 if (!m_polylinenode || !oldNode) {
123 m_polylinenode = new MapPolylineNodeOpenGLExtruded();
124 *visibleNode = static_cast<VisibleNode *>(m_polylinenode);
125 if (oldNode)
126 delete oldNode;
127 } else {
128 m_polylinenode = static_cast<MapPolylineNodeOpenGLExtruded *>(oldNode);
129 }
130
131 const QMatrix4x4 &combinedMatrix = m_map->geoProjection().qsgTransform();
132 const QDoubleVector3D &cameraCenter = m_map->geoProjection().centerMercator();
133
134 if (m_borderGeometry.isScreenDirty()) {
135 /* Do the border update first */
136 m_polylinenode->update(color(),
137 float(width()),
138 &m_borderGeometry,
139 combinedMatrix,
140 cameraCenter,
141 Qt::SquareCap,
142 true,
143 zoomForLOD(int(m_map->cameraData().zoomLevel())));
144 m_borderGeometry.setPreserveGeometry(false);
145 m_borderGeometry.markClean();
146 }
147
148 if (!m_polylinenode->isSubtreeBlocked() ) {
149 m_polylinenode->setSubtreeBlocked(false);
150 root->appendChildNode(m_polylinenode);
151 return m_polylinenode;
152 } else {
153 delete m_polylinenode;
154 m_polylinenode = nullptr;
155 *visibleNode = nullptr;
156 return nullptr;
157 }
158 }
159
path() const160 QList<QGeoCoordinate> QMapPolylineObjectPrivateQSG::path() const
161 {
162 return m_path.path();
163 }
164
setPath(const QList<QGeoCoordinate> & path)165 void QMapPolylineObjectPrivateQSG::setPath(const QList<QGeoCoordinate> &path)
166 {
167 m_path.setPath(path);
168 markSourceDirty();
169 updateGeometry();
170 if (m_map)
171 emit m_map->sgNodeChanged();
172 }
173
setColor(const QColor & color)174 void QMapPolylineObjectPrivateQSG::setColor(const QColor &color)
175 {
176 QMapPolylineObjectPrivateDefault::setColor(color);
177
178 if (m_map)
179 emit m_map->sgNodeChanged();
180 }
181
setWidth(qreal width)182 void QMapPolylineObjectPrivateQSG::setWidth(qreal width)
183 {
184 QMapPolylineObjectPrivateDefault::setWidth(width);
185
186 if (m_map)
187 emit m_map->sgNodeChanged();
188 }
189
clone()190 QGeoMapObjectPrivate *QMapPolylineObjectPrivateQSG::clone()
191 {
192 return new QMapPolylineObjectPrivateQSG(static_cast<QMapPolylineObjectPrivate &>(*this));
193 }
194
geoShape() const195 QGeoShape QMapPolylineObjectPrivateQSG::geoShape() const
196 {
197 return m_path;
198 }
199
markSourceDirty()200 void QMapPolylineObjectPrivateQSG::markSourceDirty()
201 {
202 m_borderGeometry.markSourceDirty();
203 }
204
205 QT_END_NAMESPACE
206