1 /****************************************************************************
2 **
3 ** Copyright (C) 2017 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 "qgeomapitemsoverlay.h"
38 #include "qgeomappingmanagerengineitemsoverlay.h"
39 #include <QtLocation/private/qgeomap_p_p.h>
40 #include <QtQuick/qsgnode.h>
41 #include <QtQuick/qsgrectanglenode.h>
42 #include <QtQuick/qquickwindow.h>
43 
44 #ifdef LOCATIONLABS
45 #include <QtLocation/private/qmappolylineobjectqsg_p_p.h>
46 #include <QtLocation/private/qmappolygonobjectqsg_p_p.h>
47 #include <QtLocation/private/qmapcircleobjectqsg_p_p.h>
48 #include <QtLocation/private/qmaprouteobjectqsg_p_p.h>
49 #include <QtLocation/private/qmapiconobjectqsg_p_p.h>
50 #include <QtLocation/private/qdeclarativepolylinemapitem_p.h>
51 #include <QtLocation/private/qgeomapobjectqsgsupport_p.h>
52 #endif
53 
54 QT_BEGIN_NAMESPACE
55 
56 class QGeoMapItemsOverlayPrivate : public QGeoMapPrivate
57 {
58     Q_DECLARE_PUBLIC(QGeoMapItemsOverlay)
59 public:
60     QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine, QGeoMapItemsOverlay *map);
61     virtual ~QGeoMapItemsOverlayPrivate();
62 
63 #ifdef LOCATIONLABS
64     QGeoMapObjectPrivate *createMapObjectImplementation(QGeoMapObject *obj) override;
65     virtual QList<QGeoMapObject *> mapObjects() const override;
66     void removeMapObject(QGeoMapObject *obj);
67     void updateMapObjects(QSGNode *root, QQuickWindow *window);
68     QList<QObject *>mapObjectsAt(const QGeoCoordinate &coordinate) const;
69 
70     QGeoMapObjectQSGSupport m_qsgSupport;
71 #endif
72 
73     void updateObjectsGeometry();
74 
75     void setVisibleArea(const QRectF &visibleArea) override;
76     QRectF visibleArea() const override;
77 
78 protected:
79     void changeViewportSize(const QSize &size) override;
80     void changeCameraData(const QGeoCameraData &oldCameraData) override;
81     void changeActiveMapType(const QGeoMapType mapType) override;
82 
83     QRectF m_visibleArea;
84 };
85 
QGeoMapItemsOverlay(QGeoMappingManagerEngineItemsOverlay * engine,QObject * parent)86 QGeoMapItemsOverlay::QGeoMapItemsOverlay(QGeoMappingManagerEngineItemsOverlay *engine, QObject *parent)
87     : QGeoMap(*(new QGeoMapItemsOverlayPrivate(engine, this)), parent)
88 {
89 
90 }
91 
~QGeoMapItemsOverlay()92 QGeoMapItemsOverlay::~QGeoMapItemsOverlay()
93 {
94 }
95 
capabilities() const96 QGeoMap::Capabilities QGeoMapItemsOverlay::capabilities() const
97 {
98     return Capabilities(SupportsVisibleRegion
99                         | SupportsSetBearing
100                         | SupportsAnchoringCoordinate);
101 }
102 
createMapObjectImplementation(QGeoMapObject * obj)103 bool QGeoMapItemsOverlay::createMapObjectImplementation(QGeoMapObject *obj)
104 {
105 #ifndef LOCATIONLABS
106     Q_UNUSED(obj);
107     return false;
108 #else
109     Q_D(QGeoMapItemsOverlay);
110     return d->m_qsgSupport.createMapObjectImplementation(obj, d);
111 #endif
112 }
113 
updateSceneGraph(QSGNode * node,QQuickWindow * window)114 QSGNode *QGeoMapItemsOverlay::updateSceneGraph(QSGNode *node, QQuickWindow *window)
115 {
116 #ifndef LOCATIONLABS
117     Q_UNUSED(window);
118     return node;
119 #else
120     Q_D(QGeoMapItemsOverlay);
121 
122     QSGRectangleNode *mapRoot = static_cast<QSGRectangleNode *>(node);
123     if (!mapRoot)
124         mapRoot = window->createRectangleNode();
125 
126     mapRoot->setRect(QRect(0, 0, viewportWidth(), viewportHeight()));
127     mapRoot->setColor(QColor(0,0,0,0));
128 
129     d->updateMapObjects(mapRoot, window);
130     return mapRoot;
131 #endif
132 }
133 
removeMapObject(QGeoMapObject * obj)134 void QGeoMapItemsOverlay::removeMapObject(QGeoMapObject *obj)
135 {
136 #ifndef LOCATIONLABS
137     Q_UNUSED(obj);
138 #else
139     Q_D(QGeoMapItemsOverlay);
140     d->removeMapObject(obj);
141 #endif
142 }
143 
mapObjectsAt(const QGeoCoordinate & coordinate) const144 QList<QObject *> QGeoMapItemsOverlay::mapObjectsAt(const QGeoCoordinate &coordinate) const
145 {
146 #ifdef LOCATIONLABS
147     Q_D(const QGeoMapItemsOverlay);
148     return d->mapObjectsAt(coordinate);
149 #else
150     return QGeoMap::mapObjectsAt(coordinate);
151 #endif
152 }
153 
setVisibleArea(const QRectF & visibleArea)154 void QGeoMapItemsOverlayPrivate::setVisibleArea(const QRectF &visibleArea)
155 {
156     Q_Q(QGeoMapItemsOverlay);
157     const QRectF va = clampVisibleArea(visibleArea);
158     if (va == m_visibleArea)
159         return;
160 
161     m_visibleArea = va;
162     m_geoProjection->setVisibleArea(va);
163 
164     q->sgNodeChanged();
165 }
166 
visibleArea() const167 QRectF QGeoMapItemsOverlayPrivate::visibleArea() const
168 {
169     return m_visibleArea;
170 }
171 
QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay * engine,QGeoMapItemsOverlay * map)172 QGeoMapItemsOverlayPrivate::QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine, QGeoMapItemsOverlay *map)
173     : QGeoMapPrivate(engine, new QGeoProjectionWebMercator)
174 {
175 #ifndef LOCATIONLABS
176     Q_UNUSED(map);
177 #else
178     m_qsgSupport.m_map = map;
179 #endif
180 }
181 
~QGeoMapItemsOverlayPrivate()182 QGeoMapItemsOverlayPrivate::~QGeoMapItemsOverlayPrivate()
183 {
184 }
185 
186 #ifdef LOCATIONLABS
createMapObjectImplementation(QGeoMapObject * obj)187 QGeoMapObjectPrivate *QGeoMapItemsOverlayPrivate::createMapObjectImplementation(QGeoMapObject *obj)
188 {
189     return m_qsgSupport.createMapObjectImplementationPrivate(obj);
190 }
191 
mapObjects() const192 QList<QGeoMapObject *> QGeoMapItemsOverlayPrivate::mapObjects() const
193 {
194     return m_qsgSupport.mapObjects();
195 }
196 
removeMapObject(QGeoMapObject * obj)197 void QGeoMapItemsOverlayPrivate::removeMapObject(QGeoMapObject *obj)
198 {
199     m_qsgSupport.removeMapObject(obj);
200 }
201 
updateMapObjects(QSGNode * root,QQuickWindow * window)202 void QGeoMapItemsOverlayPrivate::updateMapObjects(QSGNode *root, QQuickWindow *window)
203 {
204     m_qsgSupport.updateMapObjects(root, window);
205 }
206 
mapObjectsAt(const QGeoCoordinate & coordinate) const207 QList<QObject *> QGeoMapItemsOverlayPrivate::mapObjectsAt(const QGeoCoordinate &coordinate) const
208 {
209     // ToDo: use a space partitioning strategy
210     QList<QObject *> res;
211     for (const auto o: mapObjects()) {
212         // explicitly handle lines
213         bool contains = false;
214         if (o->type() == QGeoMapObject::PolylineType ) {
215             QMapPolylineObject *mpo = static_cast<QMapPolylineObject *>(o);
216             qreal mpp = QLocationUtils::metersPerPixel(m_cameraData.zoomLevel(), coordinate);
217             QGeoPath path = o->geoShape();
218             path.setWidth(mpp * mpo->border()->width());
219             contains = path.contains(coordinate);
220         } else if (o->type() == QGeoMapObject::RouteType) {
221             qreal mpp = QLocationUtils::metersPerPixel(m_cameraData.zoomLevel(), coordinate);
222             QGeoPath path = o->geoShape();
223             path.setWidth(mpp * 4); // MapRouteObjectQSG has a hardcoded 4 pixels width;
224             contains = path.contains(coordinate);
225         } else {
226             contains = o->geoShape().contains(coordinate);
227         }
228 
229         if (contains)
230             res.append(o);
231     }
232     return res;
233 }
234 #endif
235 
updateObjectsGeometry()236 void QGeoMapItemsOverlayPrivate::updateObjectsGeometry()
237 {
238 #ifdef LOCATIONLABS
239     m_qsgSupport.updateObjectsGeometry();
240 #endif
241 }
242 
changeViewportSize(const QSize &)243 void QGeoMapItemsOverlayPrivate::changeViewportSize(const QSize &/*size*/)
244 {
245     updateObjectsGeometry();
246 }
247 
changeCameraData(const QGeoCameraData &)248 void QGeoMapItemsOverlayPrivate::changeCameraData(const QGeoCameraData &/*oldCameraData*/)
249 {
250     updateObjectsGeometry();
251 }
252 
changeActiveMapType(const QGeoMapType)253 void QGeoMapItemsOverlayPrivate::changeActiveMapType(const QGeoMapType /*mapType*/)
254 {
255     updateObjectsGeometry();
256 }
257 
258 QT_END_NAMESPACE
259 
260 
261 
262 
263